BZOJ 2527 Meteors

Posted on 2016-05-21 16:22  ziliuziliu  阅读(118)  评论(0编辑  收藏  举报

整体二分:二分操作。

首先,memset很慢。

其次,最好开long long。

然后,最后再下一场inf流星雨保证能够出解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 300500
#define inf 1000000010
using namespace std;
long long n,m,k,o[maxn],p[maxn],id[maxn],nxt[maxn],g[maxn],val[maxn],ans[maxn];
long long cur[maxn],tmp[maxn];
long long x,y,z,tol[maxn],tor[maxn];
struct meteor
{
    long long l,r,a;
}q[maxn];
void addcon(long long con,long long now)
{
    nxt[now]=g[con];
    g[con]=now;
}
void addmet(long long left,long long right,long long a,long long now)
{
    q[now].l=left;
    q[now].r=right;
    q[now].a=a;
}
long long lowbit(long long x)
{
    return ((-x)&x);
}
void modify(long long now,long long x)
{
    for (long long i=now;i<=m;i+=lowbit(i))
        val[i]+=x;
}
void modifys(long long now,long long x)
{
    if (q[now].l<=q[now].r) 
    {
        modify(q[now].l,x);
        if (q[now].r+1<=m) modify(q[now].r+1,-x);
    }
    else
    {
        modify(q[now].l,x);
        modify(1,x);
        modify(q[now].r+1,-x);
    }
}
long long query(long long x)
{
    long long ret=0;
    for (long long i=x;i>=1;i-=lowbit(i))
        ret+=val[i];
    return ret;
}
void half_solve(long long head,long long tail,long long left,long long right)
{
    if (head>tail) return;
    long long lsum=0,rsum=0;
    if (left==right)
    {
        for (long long i=head;i<=tail;i++)
            ans[id[i]]=left;
        return;
    }
    long long mid=(left+right)>>1;
    for (long long i=left;i<=mid;i++)
        modifys(i,q[i].a);
    for (long long i=head;i<=tail;i++)
    {
        tmp[id[i]]=0;
        for (long long j=g[id[i]];j;j=nxt[j])
        {
            tmp[id[i]]+=query(j);
            if (cur[id[i]]+tmp[id[i]]>p[id[i]]) break;
        }
        if (cur[id[i]]+tmp[id[i]]>=p[id[i]]) tol[++lsum]=id[i];
        else {cur[id[i]]+=tmp[id[i]];tor[++rsum]=id[i];}
    }
    for (long long i=left;i<=mid;i++)
        modifys(i,-q[i].a);
    for (long long i=1;i<=lsum;i++) id[head-1+i]=tol[i];
    for (long long i=1;i<=rsum;i++) id[head-1+lsum+i]=tor[i];
    half_solve(head,head+lsum-1,left,mid);
    half_solve(head+lsum,tail,mid+1,right);
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for (long long i=1;i<=m;i++)
    {
        scanf("%lld",&o[i]);
        addcon(o[i],i);
    }
    for (long long i=1;i<=n;i++)
    {
        scanf("%lld",&p[i]);
        id[i]=i;
    }
    scanf("%lld",&k);
    for (long long i=1;i<=k;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        addmet(x,y,z,i);
    }
    k++;addmet(1,n,inf,k);
    half_solve(1,n,1,k);
    for (long long i=1;i<=n;i++)
    {
        if (ans[i]==k) printf("NIE\n");
        else printf("%lld\n",ans[i]);
    }
    return 0;
}