应用范围
对于区间内每一组修改,如果修改范围是连续的,并且非在线,基于这种特性,我们可以用差分序列
方法
用一个数组a记录每位和前一位的差,区间修改时就对数组a的区间首端加上x,再在区间末端+1处减去x,最终用前缀和数组加以统计,就可以得出所需的值。
例题
http://cogs.pro/cogs/problem/problem.php?pid=1266
/************************************************************************************** 差分序列 **************************************************************************************/ #include<cstdio> #include<cctype> using namespace std; #define maxn 1000005 char * ptr=new char[50000000]; inline void in(int &x){ while(*ptr<'0'||*ptr>'9')++ptr; x=0; while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0'; } int a[maxn],d[maxn],l[maxn],r[maxn];//a是差分序列 int main(){ freopen("classrooms.in","r",stdin); freopen("classrooms.out","w",stdout); fread(ptr,1,50000000,stdin); int n,m,x,t=0;in(n),in(m); for(int i=1;i<=n;i++){ in(x),a[i]=x-t, t=x; } for(int j=1;j<=m;j++){ in(d[j]),in(l[j]),in(r[j]); a[l[j]]-=d[j],a[++r[j]]+=d[j];//对差分序列进行修改 } x=0,t=m; for(int i=1;i<=n;i++){ x+=a[i]; while(x<0&&t){//订单如果不能满足的话就从最后一个订单开始取消,直到订单满足或者没有订单 ,最后t一定是第一个满足不了的订单 if(r[t]>i){//取消订单 if(l[t]<=i)x+=d[t]; else a[l[t]]+=d[t]; a[r[t]]-=d[t]; } t--; } } if(t<m) printf("-1 %d",++t); else printf("0"); return 0; }