2527: [Poi2011]Meteors|整体二分

来源:互联网 发布:一根网线几个淘宝店铺 编辑:程序博客网 时间:2024/05/19 18:48

二分一个答案,对这个答案的国家
分到左边一组,其余的分到右面一组继续向下分治递归处理
ps迷之WA可能是过程中爆了longlong !!

#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<vector>#include<queue>#include<cmath>#include<set>#include<map>#define lowbit(x) (x&(-x))#define N 310000#define ll long longusing namespace std;int sc(){    int i=0,f=1;char c=getchar();    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();    return i*f;}struct W{int l,r,v;}a[N];int head[N],nxt[N],lst[N],nd[N];int q[N],q1[N],q2[N],ans[N],now;ll tr[N],sum[N];int n,m,tot,K;void insert(int x,int y){    lst[++tot]=y;nxt[tot]=head[x];head[x]=tot;}void change(int x,int f){    for(;x<=m;x+=lowbit(x))        tr[x]+=f;}void updata(int x,int f){    if(a[x].r>=a[x].l)    {        change(a[x].l,f*a[x].v);        change(a[x].r+1,-f*a[x].v);    }    else    {        change(a[x].l,f*a[x].v);        change(a[x].r+1,-f*a[x].v);        change(1,f*a[x].v);    }}ll ask(int x){    ll ans=0;    for(;x;x-=lowbit(x))         ans+=tr[x];    return ans;}void solve(int s,int t,int l,int r){    if(t<s)return;    if(l==r)    {        for(int i=s;i<=t;i++)            ans[q[i]]=l;        return;    }    int mid=l+r>>1;    while(now<mid)updata(++now,1);    while(now>mid)updata(now--,-1);    int p1=0,p2=0;    for(int i=s;i<=t;i++)    {        ll sum=0;        for(int j=head[q[i]];j;j=nxt[j])        {            sum+=ask(lst[j]);            if(sum>=nd[q[i]])break;//sum答案会爆long long!!!!!!!!!!!!!!!!!!!!         }        if(sum>=nd[q[i]])             q1[++p1]=q[i];        else            q2[++p2]=q[i];    }    for(int i=1;i<=p1;i++) q[s+i-1]=q1[i];    for(int i=1;i<=p2;i++) q[s+p1+i-1]=q2[i];    solve(s,s+p1-1,l,mid),solve(s+p1,t,mid+1,r);}int main(){    n=sc(),m=sc();    for(int i=1;i<=m;i++)         insert(sc(),i);    for(int i=1;i<=n;i++)        nd[q[i]=i]=sc();    K=sc();    for(int i=1;i<=K;i++)        a[i].l=sc(),a[i].r=sc(),a[i].v=sc();    solve(1,n,1,K+1);    for(int i=1;i<=n;i++)        if(ans[i]<=K)            printf("%d\n",ans[i]);        else puts("NIE");    return 0;}
0 0
原创粉丝点击