文章目录
差分在ACM竞赛中的应用
众所周知,前缀和是差是原序列,差分的合适原序列
B是A的差分数组
B[1]=A[1],B[i]=A[i]−A[i−1](2<=i<=n)
1 一维差分
0304 IncDec Sequence
0304 IncDec Sequence
给定一个长度为 n(n≤105)的数列 a1,a2,…,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
const int maxn = 1e5+10;
LL a[maxn],b[maxn];
int main(void)
{
int n;cin>>n;
for(int i = 1;i <= n ;++i)
scanf("%lld",&a[i]);
for(int i = 1;i <= n; ++i)
b[i] = a[i]-a[i-1];
LL sum1,sum2;
sum1 = sum2 = 0;
for(int i = 2;i <= n; ++i)
if(b[i] > 0)
sum1 += b[i];
else
sum2 += abs(b[i]);
cout<<max(sum1,sum2)<<endl;
cout<<abs(sum1-sum2)+1<<endl;
return 0;
}
2 二维差分
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL mat[10000007];
int r, c;
int n, q;
inline void m(int x, int y,int p) {
if(x < 0 || x >= r || y < 0 ||y >= c) return ;
// cout<<x*c+y<<endl;
mat[x*c+y] += p;
}
void solve(int t) {
for (int i= 0; i<r; ++i) {
for (int j= 0; j< c; ++j) {
if(t&&mat[i*c+j])
mat[i*c+j] = 1;
if(i)
mat[i*c+j] += mat[(i-1)*c+j];
if(j)
mat[i*c+j] += mat[i*c+(j-1)];
if(i&&j)
mat[i*c+j] -= mat[(i-1)*c+(j-1)];
}
}
}
int main() {
// ios::sync_with_stdio(0);
while(~scanf("%d%d",&r,&c)) {
memset(mat,0,sizeof(mat));
// cout<<r<<" "<<c<<endl;
int x1,y1,x2,y2;
int n;scanf("%d",&n);
for (int i=0; i<n; ++i) {
// cin >> x1>>y1>>x2>>y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1--,y1--,x2--,y2--;
// cout<<x1<<" "<<y1<<" "<<x2<< " "<<y2<<endl;
m(x1,y1,1);
m(x2+1,y1,-1);
m(x1,y2+1,-1);
m(x2+1,y2+1,1);
}
// cout<<mat[7]<<endl;
// for(int i = 0;i < r; ++i,cout<<endl)
// for(int j = 0;j < c; ++j)
// cout<<mat[i*c+j]<<" ";
// cout<<endl;
solve(0);
solve(1);
// for(int i = 0;i < r; ++i,cout<<endl)
// for(int j = 0;j < c; ++j)
// cout<<mat[i*c+j]<<" ";
int q;scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1--,y1--,x2--,y2--;
LL sum = mat[x2*c+y2],sum1 = x2*c+y2;
// LL sum1 = 0;
sum1 = (x2-x1+1)*(y2-y1+1);
if(x1)
sum -= mat[(x1-1)*c+y2];//,sum1 -= (x1-1)*c+y2;
if(y1)
sum -= mat[x2*c+y1-1];//,sum1 -= x2*c+y1-1;
if(x1&&y1)
sum += mat[(x1-1)*c+(y1-1)];//,sum1 += (x1-1)*c+y1-1;
// cout<<sum<<endl;
// cout<<sum<<endl;
// cout<<sum1<<endl;
puts(sum==sum1?"YES":"NO");
}
}
return 0;
}