前缀和
【例题】BZOJ1218 激光炸弹
计算二位前缀和,再利用容斥原理计算出答案即可。
1 #include2 #include 3 #include 4 #include 5 using namespace std; 6 const int maxn=5000+10; 7 int n, r, sum[maxn][maxn]; 8 9 int main() { 10 scanf("%d%d", &n, &r); 11 int x, y, v, maxx=0, maxy=0; 12 maxx=maxy=r; 13 for (int i=1; i<=n; ++i) { 14 scanf("%d%d%d", &x, &y, &v); 15 ++x; ++y; 16 maxx=max(maxx, x); maxy=max(maxy, y); 17 sum[x][y]=v; 18 } 19 for (int i=1; i<=maxx; ++i) { 20 for (int j=1; j<=maxy; ++j) { 21 sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; 22 } 23 } 24 //枚举面积为r的正方形 25 int ans=0; 26 for (int i=r; i<=maxx; ++i) { 27 for (int j=r; j<=maxy; ++j) { 28 ans=max(ans, sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]); 29 } 30 } 31 printf("%d\n", ans); 32 return 0; 33 }
差分
【例题】CH0304 IncDec Sequence
求出序列a的差分序列b,令bn+1=0,目标是将把b2,b3...bn变为全0。
把序列a区间[l,r]加d,其差分序列的变化为Bl加d,Br+1减d。
从b1,b2...bn中任选两个数的方法可以分为4类:
1.选bi和bj
2.选b1和bj
3.选bi和bn+1
4.选b1和bn+1,这种选法没有意义
设整数总和为p,负数总和为q,首先以正负数匹配的方式尽量选择操作1,可执行min(p,q)次。
剩余|p-q|个未配对,执行操作2和操作3,共需|p-q|次。
所以最少操作次数为min(p,q)+|p-q|=max(p,q)次,根据操作2,3的选择情况,能产生|p-q|+1种b1的值,即序列a可能有|p-q|+1种。
1 #include2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 const int maxn=100000+10; 8 long long n, a[maxn], s[maxn], p=0, q=0; 9 10 int main() { 11 scanf("%lld", &n); 12 for (int i=1; i<=n; ++i) 13 scanf("%lld", &a[i]); 14 s[1]=a[1]; s[n+1]=0; 15 for (int i=2; i<=n; ++i) { 16 s[i]=a[i]-a[i-1]; 17 } 18 for (int i=2; i<=n; ++i) { 19 if (s[i]>0) p+=s[i]; 20 else if (s[i]<0) q-=s[i]; 21 } 22 printf("%lld\n%lld\n", max(p,q), abs(p-q)+1); 23 return 0; 24 }
【例题】POJ3263 Tallest Cow
若有一条关系指明Ai和Bi可以互相看见,就将他们数组中Ai+1到Bi-1的数减去1,最终得到所有牛与最高的牛p的相对身高关系。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include