十字爆破(二维转一维)

十字爆破(二维转一维)

传送门

一开始看成了 n , m ≤ 1 e 6 n,m\leq1e6 n,m1e6把我人看傻了,结果第二天发现是 n × m ≤ 1 e 6 n\times m\leq1e6 n×m1e6

思路:二维转一维,从下标 ( 0 , 0 ) (0,0) (0,0)开始记为 0 0 0,编号 x x x表示 ( x / m , x % m ) (x/m,x\%m) (x/m,x%m)

求每行,每列之和,用两个数组储存前缀和即可。

最后 a n s [ i ] [ j ] = p r e [ i ] + p r e [ j ] − a [ i × m + j ] ans[i][j]=pre[i]+pre[j]-a[i\times m+j] ans[i][j]=pre[i]+pre[j]a[i×m+j]

AC代码:

#include
using namespace std;
typedef long long ll;
const int N=1e6+5;
#define mst(a) memset(a,0,sizeof a)
ll pre1[N],pre2[N];
int a[N];
int main(){
	int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n*m;i++)
        scanf("%d",&a[i]),pre1[i/m]+=a[i],pre2[i%m]+=a[i];
    for(int i=0;i<n;i++){      
            for(int j=0;j<m;j++)
               printf("%lld ",pre1[i]+pre2[j]-a[i*m+j]);
        puts("");
    }	
	return 0;
} 

你可能感兴趣的:(前缀和)