差分序列

应用范围

对于区间内每一组修改,如果修改范围是连续的,并且非在线,基于这种特性,我们可以用差分序列

方法

用一个数组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;
}

 

posted @ 2017-08-02 18:21  Bennettz  阅读(2114)  评论(0编辑  收藏  举报