應用范圍
對於區間內每一組修改,如果修改范圍是連續的,並且非在線,基於這種特性,我們可以用差分序列
方法
用一個數組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\n%d",++t); else printf("0"); return 0; }