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]<<'\n';
    }
}
posted @ 2017-12-19 13:51  TRTTG  阅读(223)  评论(0编辑  收藏  举报