• bzoj2527: [Poi2011]Meteors


    http://www.lydsy.com/JudgeOnline/problem.php?id=2527

    整体二分

    区间加,单点查,树状数组维护差分序列

    注意 累积可能会爆long long,所以一满足要求就break

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 300001
    
    #define lowbit(x) x&-x
    
    typedef long long LL;
    
    int m,k;
    
    int tot,front[N],nxt[N],to[N];
    
    struct node
    {
        bool ty;
        int l,r,id;
        int num,cur;
    }e[N<<1],tmp1[N<<1],tmp2[N<<1];
    
    int need[N],ans[N];
    
    LL have[N];
    
    LL c[N+10];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c))  c=getchar(); 
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar();  }
    }
    
    void add(int x,int y)
    {
        to[++tot]=y; nxt[tot]=front[x]; front[x]=tot; 
    }
    
    void change(int x,int y)
    {
        while(x<=m)
        {
            c[x]+=y;
            x+=lowbit(x);
        }
    }
    
    LL query(int x)
    {
        LL sum=0;
        while(x)
        {
            sum+=c[x];
            x-=lowbit(x);
        }
        return sum;
    }
    
    void solve(int head,int tail,int l,int r)
    {
        if(head>tail) return;
        if(l==r)
        {
            for(int i=head;i<=tail;++i)
                if(!e[i].ty) ans[e[i].l]=l;
            return;
        }
        int mid=l+r>>1;
        for(int i=head;i<=tail;++i)
        {
            if(e[i].ty && e[i].id<=mid) 
            {
                if(e[i].l<=e[i].r)
                {
                    change(e[i].l,e[i].num);
                    change(e[i].r+1,-e[i].num);
                }
                else
                {
                    change(e[i].l,e[i].num);
                    change(1,e[i].num);
                    change(e[i].r+1,-e[i].num);
                }
            }
            else if(!e[i].ty) 
            {
                have[e[i].l]=0;
                for(int j=front[e[i].l];j;j=nxt[j]) 
                {
                    have[e[i].l]+=query(to[j]);
                    if(have[e[i].l]>=e[i].num) break;
                }
                    
            }
        }
        for(int i=head;i<=tail;++i)
        {
            if(e[i].ty && e[i].id<=mid) 
            {
                if(e[i].l<=e[i].r)
                {
                    change(e[i].l,-e[i].num);
                    change(e[i].r+1,e[i].num);
                }
                else
                {
                    change(e[i].l,-e[i].num);
                    change(1,-e[i].num);
                    change(e[i].r+1,e[i].num);
                }
            }
        }
        int ll=0,rr=0;
        for(int i=head;i<=tail;++i)
        {
            if(!e[i].ty)
            {
                if(e[i].cur+have[e[i].l]>=e[i].num) tmp1[++ll]=e[i];
                else
                {
                    e[i].cur+=have[e[i].l];
                    tmp2[++rr]=e[i];
                }
            }
            else
            {
                if(e[i].id<=mid) tmp1[++ll]=e[i];
                else tmp2[++rr]=e[i];
            }
        }
        for(int i=1;i<=ll;++i) e[head+i-1]=tmp1[i];
        for(int i=1;i<=rr;++i) e[head+ll+i-1]=tmp2[i];
        solve(head,head+ll-1,l,mid);
        solve(head+ll,tail,mid+1,r);
    }
    
    int main()
    {
        int n;
        read(n); read(m);
        int x,y,z;
        for(int i=1;i<=m;++i)
        {
            read(x);
            add(x,i);
        } 
        for(int i=1;i<=n;++i) read(need[i]);
        read(k);
        for(int i=1;i<=k;++i)
        {
            read(e[i].l); 
            read(e[i].r);
            read(e[i].num);
            e[i].ty=true;
            e[i].id=i;
        }
        k++;
        e[k].l=1; 
        e[k].r=m; 
        e[k].num=1e9;
        e[k].ty=true;
        e[k].id=k;
        for(int i=1;i<=n;++i)
        {
            e[k+i].l=i;
            e[k+i].num=need[i];
        }
        solve(1,n+k,1,k);
        for(int i=1;i<=n;++i)
        {
            if(ans[i]==k) puts("NIE");
            else cout<<ans[i]<<'
    ';
        }
    }
  • 相关阅读:
    链表相交
    环路检测
    lambada表达式对集合的过滤和相互转换
    lambda表达式对集合的遍历
    centos7常用命令
    小程序文件
    扫码登录
    位操作
    使用json-lib转换对象为字符串时的特殊处理
    javac 编译异常总结
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8065159.html
Copyright © 2020-2023  润新知