BZOJ 2527 [POI2011]MET-Meteors (整体二分+树状数组)
题目大意:略
整体二分裸题
考虑只有一个国家的情况如何处理
对询问数量二分答案,暴力$O(m)$打差分,求前缀和验证,时间是$O(mlogK)$
如果有$n$个国家,就是$O(nmlogK)$,非常不优秀的时间复杂度
发现我们对于每个国家都进行一次二分很浪费时间
考虑把国家分成一定数量的集合
每次二分出一个答案$mid$
把集合内的国家按照能否满足要求分成两个集合$S1,S2$
如果能满足要求,当前询问的mid不一定是最优解,答案范围一定是$[l,mid]$
如果不能满足要求,当前$mid$不能作为答案,答案范围只能是$[mid+1,r]$
$(l,mid,S1),(mid+1,r,S2)$递归分治处理,用树状数组维护即可
时间$O((K+n)logKlogm)$
1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 300100 6 #define ll long long 7 #define dd double 8 #define inf 233333333 9 using namespace std; 10 11 int gint() 12 { 13 int ret=0,fh=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 15 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 16 return ret*fh; 17 } 18 int n,m,Q,K; 19 struct BIT{ 20 ll sum[N1]; 21 void update(int x,int w){ for(int i=x;i<=m;i+=(i&(-i))) sum[i]+=w; } 22 ll query(int x){ ll ans=0; for(int i=x;i;i-=(i&(-i))) ans+=sum[i]; return ans; } 23 void clr(int x){ for(int i=x;i<=m;i+=(i&(-i))) sum[i]=0; } 24 }s; 25 struct node{int l,r,w;}q[N1]; 26 vector<int>son[N1]; 27 int que[N1*3],tl,ans[N1],id[N1],tmp[N1],p[N1]; 28 void alldic(int l,int r,int ql,int qr) 29 { 30 if(l>r||ql>qr) return; 31 int qmid=(ql+qr)>>1,i,j,x,S=l,E=r; ll res; 32 for(i=ql;i<=qmid;i++) 33 { 34 if(q[i].l<=q[i].r){ 35 s.update(q[i].l,q[i].w); s.update(q[i].r+1,-q[i].w); 36 que[++tl]=q[i].l; que[++tl]=q[i].r+1; 37 }else{ 38 s.update(q[i].l,q[i].w); s.update(1,q[i].w); s.update(q[i].r+1,-q[i].w); 39 que[++tl]=1; que[++tl]=q[i].l; que[++tl]=q[i].r+1; 40 } 41 } 42 for(i=l;i<=r;i++) 43 { 44 x=id[i]; res=p[x]; 45 for(j=0;j<son[x].size();j++) 46 { 47 res-=s.query(son[x][j]); 48 if(res<=0) { ans[x]=qmid; tmp[S++]=x; break;} 49 } 50 if(res>0) { p[x]=res; tmp[E--]=x; } 51 } 52 for(i=l;i<=r;i++) id[i]=tmp[i]; 53 while(tl) s.clr(que[tl--]); 54 alldic(l,S-1,ql,qmid-1); alldic(E+1,r,qmid+1,qr); 55 } 56 57 int main() 58 { 59 scanf("%d%d",&n,&m); 60 int i,j,k,x,y,z; 61 for(i=1;i<=m;i++){ x=gint(),son[x].push_back(i); } 62 for(i=1;i<=n;i++){ p[i]=gint(); id[i]=i;} 63 scanf("%d",&Q); 64 for(i=1;i<=Q;i++){ q[i].l=gint(); q[i].r=gint(); q[i].w=gint(); } 65 alldic(1,n,1,Q); 66 for(i=1;i<=n;i++) 67 { 68 if(!ans[i]) puts("NIE"); 69 else printf("%d\n",ans[i]); 70 } 71 return 0; 72 }