BZOJ2527: [Poi2011]Meteors
这个。
。。一開始用的是longlong 然后改成int就wa了。
。
。。
时间垫底。。。。。
可怕
全局分治 然后用线段树维护的时候直接永久化标记 不用下传
然后这一题和上一道树套树一样。又是由于自己傻逼少了一倍的线段树节点然后一直OLE不知道怎么了。
。
。
人傻没办法
#include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<cstdlib> using namespace std; char c; inline void read(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0') a=(a<<3)+(a<<1)+c-'0',c=getchar(); } struct Segement { int l,r,flag; }Tree[2000001]; void Segement_Build(int place,int l,int r) { Tree[place].l=l;Tree[place].r=r; if(l^r) Segement_Build(place<<1,l,(l+r)>>1),Segement_Build(place<<1|1,((l+r)>>1)+1,r); } int Segement_data(int place,int l) { if(Tree[place].l==Tree[place].r) return Tree[place].flag; if(Tree[place<<1].r>=l) return Segement_data(place<<1,l)+Tree[place].flag; return Segement_data(place<<1|1,l)+Tree[place].flag; } int n,m; void Segement_ADD(int place,int l,int r,int delta) { if(Tree[place].l>=l&&Tree[place].r<=r) {Tree[place].flag+=delta;return;} if(Tree[place<<1].r>=l) Segement_ADD(place<<1,l,r,delta); if(Tree[place<<1|1].l<=r) Segement_ADD(place<<1|1,l,r,delta); } struct Opt { int x,y,z; }Line[400001]; inline void add(int a,int b,int d){ if(a>b)Segement_ADD(1,a,m,d),Segement_ADD(1,1,b,d); else Segement_ADD(1,a,b,d);} inline void Plus(int x,int k){add(Line[x].x,Line[x].y,Line[x].z*k);} vector<int>Country[400001]; int T=0; int ID[400001]; int need[400001]; int ans[400001]; bool Mark[400001]; int tp[400001]; void Solve(int IDl,int IDr,int ansl,int ansr) { if(IDl>IDr)return; if(ansl>ansr)return; if(ansl==ansr) { for(int i=IDl;i<=IDr;i++) ans[ID[i]]=ansl; return; } int ansM=(ansl+ansr)>>1; while(T<=ansM)T++,Plus(T,1); while(T>ansM)Plus(T,-1),T--; int i,j,k,cnt=0; int now; for(i=IDl;i<=IDr;i++) { now=0; for(j=0;j<Country[ID[i]].size()&&now<need[ID[i]];j++) now+=Segement_data(1,Country[ID[i]][j]); if(now>=need[ID[i]]) Mark[i-IDl+1]=true,cnt++; else Mark[i-IDl+1]=false; } j=0,k=0; for(i=IDl;i<=IDr;i++) if(Mark[i-IDl+1]) tp[++j]=ID[i]; else tp[++k+cnt]=ID[i]; for(i=IDl;i<=IDr;i++) ID[i]=tp[i-IDl+1]; Solve(IDl,IDl+cnt-1,ansl,ansM),Solve(IDl+cnt,IDr,ansM+1,ansr); } int q; int pr[400001]; int main() { int i,j; read(n),read(m); Segement_Build(1,1,m); Line[0].x=1; Line[0].y=m; Line[0].z=0; for(i=1;i<=m;i++) read(j),Country[j].push_back(i); for(i=1;i<=n;i++) ID[i]=i,read(need[i]); read(q); for(i=1;i<=q;i++) read(Line[i].x),read(Line[i].y),read(Line[i].z); Line[++q]=(Opt){1,m,1e9}; Solve(1,n,1,q); for(i=1;i<=n;i++) pr[ID[i]]=ans[ID[i]]; for(i=1;i<=n;i++) if(pr[i]!=q) printf("%lld\n",pr[i]); else puts("NIE"); return 0; }