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 }

 

posted @ 2019-01-03 18:20  guapisolo  阅读(138)  评论(0编辑  收藏  举报