bzoj2527: [Poi2011]Meteors

整体二分天数,然后用树状数组记录每个点采集点收集的陨石个数,暴力计算对于某个国家,是否达到要求,因为在计算过程中可能爆LL,所以边加边判。

我怎么老是把m打成n啊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

int n,m;LL s[310000];
int lowbit(int x){return x&-x;}
void change(int x,LL k)
{
    while(x<=m)
    {
        s[x]+=k;
        x+=lowbit(x);
    }
}
LL getsum(int x)
{
    LL ret=0;
    while(x>0)
    {
        ret+=s[x];
        x-=lowbit(x);
    }
    return ret;
}

//--------------bit-------------------------

int last[310000],nxt[310000];LL se[310000];
struct node
{
    int t,x,y;LL k;
}q[1100000],lq[610000],rq[610000];int len,as[310000];
LL d[310000];
void solve(int l,int r,int st,int ed)
{
    if(st>ed)return ;
    if(l==r)
    {
        for(int i=st;i<=ed;i++)
            if(q[i].k<0)as[q[i].x]=l;
        return ;
    }
    
    int mid=(l+r)/2;
    int lt=0,rt=0,be=ed+1;
    for(int i=st;i<=ed;i++)
    {
        if(q[i].k>0)
        {
            if(q[i].t<=mid)
            {
                change(q[i].x,q[i].k);
                if(q[i].y<m)change(q[i].y+1,-q[i].k);
                lq[++lt]=q[i];
            }
            else rq[++rt]=q[i];
        }
        else {be=i;break;}
    }
    
    //--------------陨石雨---------------------------- 
    
    for(int i=be;i<=ed;i++)
    {
        LL sum=0;
        for(int k=last[q[i].x];k;k=nxt[k])
        {
            sum+=getsum(k);
            if(sum>=se[q[i].x])
            {
                lq[++lt]=q[i];
                break;
            }
        }
        if(sum<se[q[i].x])
        {
            se[q[i].x]-=sum;
            rq[++rt]=q[i];
        }
    }
    
    //-------------石头够没------------------- 
    
    for(int i=st;i<=be-1;i++)
    {
        if(q[i].k>0&&q[i].t<=mid)
        {
            change(q[i].x,-q[i].k);
            if(q[i].y<m)change(q[i].y+1,q[i].k);
        }
    }
    
    //-----------还原树状数组------------------------ 
    
    for(int i=1;i<=lt;i++)q[st+i-1]=lq[i];
    for(int i=1;i<=rt;i++)q[st+lt+i-1]=rq[i];
    solve(l,mid,st,st+lt-1);
    solve(mid+1,r,st+lt,ed);
}

int main()
{
    freopen("meteors.in","r",stdin);
    freopen("meteors.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x; memset(last,0,sizeof(last));
    for(int i=1;i<=m;i++)
        scanf("%d",&x), nxt[i]=last[x], last[x]=i;
    for(int i=1;i<=n;i++)scanf("%lld",&se[i]);
    
    int Q,l,r;LL k;len=0;
    scanf("%d",&Q);
    for(int i=1;i<=Q;i++)
    {
        scanf("%d%d%lld",&l,&r,&k);
        if(l<=r)
        {
            len++;
            q[len].t=i;q[len].x=l;q[len].y=r;q[len].k=k;
        }
        else
        {
            len++;
            q[len].t=i;q[len].x=l;q[len].y=m;q[len].k=k;
            len++;
            q[len].t=i;q[len].x=1;q[len].y=r;q[len].k=k;
        }
    }
    for(int i=1;i<=n;i++)
        q[++len].k=-1, q[len].x=i;
    
    memset(d,0,sizeof(d));
    solve(1,Q+1,1,len);
    for(int i=1;i<=n;i++)
        if(as[i]==Q+1)printf("NIE\n");
        else printf("%d\n",as[i]);
    return 0;
}

 

posted @ 2018-08-09 08:25  AKCqhzdy  阅读(120)  评论(0编辑  收藏  举报