intn;// Array size.std::vector<int>a;// Array. (indexed from 1)std::vector<int>ps;// Prefix sum array.// Calculate prefix sum.voidprefix_sum(){ps=a;// Or simply:// std::partial_sum(a.begin(), a.end(), ps.begin());for(inti=1;i<=n;++i){ps[i]+=ps[i-1];}}// Query sum of elements in [l, r].intquery(intl,intr){returnps[r]-ps[l-1];}
1 2 3 4 5 6 7 8 9101112131415161718
n=0# Array sizea=[]# Array (indexed from 1)ps=[]# Prefix sum array# Calculate prefix sumdefprefix_sum():globalpsps=a[:]# Or simply:# ps = list(itertools.accumulate(a))foriinrange(1,n+1):ps[i]+=ps[i-1]# Query sum of elements in [l, r]defquery(l,r):returnps[r]-ps[l-1]
#include<algorithm>#include<iostream>#include<vector>intn,m;std::vector<std::vector<int>>a,ps;// (n + 1) x (m + 1).// Calculate the prefix sum of 2-d array.voidprefix_sum(){ps=a;for(inti=1;i<=n;++i)for(intj=1;j<=m;++j)ps[i][j]+=ps[i-1][j]+ps[i][j-1]-ps[i-1][j-1];}// Find the sum of elements in submatrix [x1, y1] to [x2, y2].intquery(intx1,inty1,intx2,inty2){returnps[x2][y2]-ps[x1-1][y2]-ps[x2][y1-1]+ps[x1-1][y1-1];}intmain(){std::cin>>n>>m;a.assign(n+1,std::vector<int>(m+1));for(inti=1;i<=n;i++)for(intj=1;j<=m;j++)std::cin>>a[i][j];prefix_sum();intans=0;for(intl=1;l<=std::min(n,m);++l)for(inti=l;i<=n;i++)for(intj=l;j<=m;j++)if(query(i-l+1,j-l+1,i,j)==l*l)ans=std::max(ans,l);std::cout<<ans<<std::endl;return0;}
n,m=0,0a=[]# (n+1) x (m+1)ps=[]# prefix sum array# Calculate the prefix sum of 2D array.defprefix_sum():globalpsps=[row[:]forrowina]# Deep copy of aforiinrange(1,n+1):forjinrange(1,m+1):ps[i][j]+=ps[i-1][j]+ps[i][j-1]-ps[i-1][j-1]# Find the sum of elements in submatrix [x1, y1] to [x2, y2].defquery(l1,r1,l2,r2):returnps[x2][y2]-ps[x1-1][y2]-ps[x2][y1-1]+ps[x1-1][y1-1]if__name__=="__main__":globaln,m,an,m=map(int,input().split())# Initialize with zero padding for 1-based indexinga=[[0]*(m+1)]for_inrange(n):row=list(map(int,input().split()))a.append([0]+row)prefix_sum()ans=0forlinrange(1,min(n,m)+1):foriinrange(l,n+1):forjinrange(l,m+1):ifquery(i-l+1,j-l+1,i,j)==l*l:ans=max(ans,l)print(ans)
intN1,N2,N3;std::vector<std::vector<std::vector<int>>>a,ps;// (N1 + 1) x (N2 + 1) x (N3 + 1).// Calculate prefix sum of 3d array.voidprefix_sum(){ps=a;// Prefix-sum for 3rd dimension.for(inti=1;i<=N1;++i)for(intj=1;j<=N2;++j)for(intk=1;k<=N3;++k)ps[i][j][k]+=ps[i][j][k-1];// Prefix-sum for 2nd dimension.for(inti=1;i<=N1;++i)for(intj=1;j<=N2;++j)for(intk=1;k<=N3;++k)ps[i][j][k]+=ps[i][j-1][k];// Prefix-sum for 1st dimension.for(inti=1;i<=N1;++i)for(intj=1;j<=N2;++j)for(intk=1;k<=N3;++k)ps[i][j][k]+=ps[i-1][j][k];}
因为考虑每一个维度的时候,都只遍历了整个数组一遍,这样的算法复杂度是 的,通常可以接受。
特例:子集和 DP
维度比较大的情形,经常出现在一类叫做 子集和(sum over subsets, SOS)的问题中。这是高维前缀和的特例。
intn;std::vector<int>diff,a;// Add v to each element in [l, r].voidadd(intl,intr,intv){diff[l]+=v;if(r<n)diff[r+1]-=v;}// Execute this after all modifications and before all queries.voidprefix_sum(){for(inti=1;i<=n;++i)a[i]=a[i-1]+diff[i];}
intn,m;std::vector<std::vector<int>>diff,a;// Add v to each element from [x1, y1] to [x2, y2].voidadd(intx1,inty1,intx2,inty2,intv){diff[x1][y1]+=v;if(x2<n)diff[x2+1][y1]-=v;if(y2<m)diff[x1][y2+1]-=v;if(x2<n&&y2<m)diff[x2+1][y2+1]+=v;}// Execute this after all modifications and before all queries.voidprefix_sum(){a=diff;for(inti=1;i<=n;++i)for(intj=1;j<=m;++j)a[i][j]+=a[i-1][j];for(inti=1;i<=n;++i)for(intj=1;j<=m;++j)a[i][j]+=a[i][j-1];}