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; }
pain and happy in the cruel world.