• 差分序列


    应用范围

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

    方法

    用一个数组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;
    }
  • 相关阅读:
    最小花费
    LOJ10090
    LOJ2436
    loj10087
    LOJ2632
    LOJ10021 Addition Chains
    LOJ10019生日蛋糕
    loj10018数的划分
    LOJ10015扩散
    loj10014数列分段二
  • 原文地址:https://www.cnblogs.com/bennettz/p/7275356.html
Copyright © 2020-2023  润新知