bzoj 2527: [Poi2011]Meteors 整体二分

        给每个国家建一个链表,这样分治过程中的复杂度就和序列长度线形相关了,无脑套整体二分就可以。

      (最坑的地方是如果所有位置都是一个国家,那么它的样本个数会爆longlong!!被这个坑了一次,大于p[i]的时候break就行了)。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #define N 300005
  7 #define int long long
  8 using namespace std;
  9 int n,m,k;
 10 vector<int>a[N];
 11 int c[N];
 12 void add(int x,int y)
 13 {
 14     for(int i=x;i<=m;i+=(i&(-i)))
 15     {
 16         c[i]+=y;
 17     }
 18 }
 19 int qur(int x)
 20 {
 21     int ans=0;
 22     for(int i=x;i;i-=(i&(-i)))
 23     {
 24         ans+=c[i];
 25     }
 26     return ans;
 27 }
 28 int q[N];
 29 int p[N];
 30 struct node
 31 {
 32     int l,r,z;
 33 }op[N];
 34 int ans[N];
 35 int tmp[2][N];
 36 void solve(int L,int R,int l,int r)
 37 {
 38     if(L>R)return ;
 39     if(l==r)
 40     {
 41         for(int i=L;i<=R;i++)
 42         {
 43             ans[q[i]]=l;
 44         }
 45         return ;
 46     }
 47     int mid=(l+r)>>1;
 48     int cnt1=0,cnt2=0;
 49     for(int i=l;i<=mid;i++)
 50     {
 51         if(op[i].l<=op[i].r)
 52         {
 53             add(op[i].l,op[i].z);add(op[i].r+1,-op[i].z);
 54         }
 55         else 
 56         {
 57             add(1,op[i].z);add(op[i].r+1,-op[i].z);add(op[i].l,op[i].z);
 58         }
 59     }
 60     for(int i=L;i<=R;i++)
 61     {
 62         int tp=0;
 63         for(int j=0;j<a[q[i]].size();j++)
 64         {
 65             tp+=qur(a[q[i]][j]);
 66             if(tp>=p[q[i]])break;
 67         }
 68         if(tp>=p[q[i]])tmp[0][++cnt1]=q[i];
 69         else p[q[i]]-=tp,tmp[1][++cnt2]=q[i];
 70     }
 71     for(int i=l;i<=mid;i++)
 72     {
 73         if(op[i].l<=op[i].r)
 74         {
 75             add(op[i].l,-op[i].z);add(op[i].r+1,op[i].z);
 76         }
 77         else 
 78         {
 79             add(1,-op[i].z);add(op[i].r+1,op[i].z);add(op[i].l,-op[i].z);
 80         }
 81     }
 82     int l1=L+cnt1-1;
 83     for(int i=1;i<=cnt1;i++)q[L+i-1]=tmp[0][i];
 84     for(int i=1;i<=cnt2;i++)q[l1+i]=tmp[1][i];
 85     solve(L,l1,l,mid);solve(l1+1,R,mid+1,r);
 86 }
 87 signed main()
 88 {
 89     scanf("%lld%lld",&n,&m);
 90     for(int i=1;i<=m;i++)
 91     {
 92         int t1;scanf("%lld",&t1);
 93         a[t1].push_back(i);
 94     }
 95     for(int i=1;i<=n;i++)scanf("%lld",&p[i]),q[i]=i;
 96     scanf("%lld",&k);
 97     for(int i=1;i<=k;i++)
 98     {
 99         scanf("%lld%lld%lld",&op[i].l,&op[i].r,&op[i].z);
100     }
101     solve(1,n,1,k+1);
102     for(int i=1;i<=n;i++)
103     {
104         if(ans[i]!=k+1)printf("%lld\n",ans[i]);
105         else puts("NIE");
106     }
107     return 0;
108 }
posted @ 2016-12-11 20:49  SD_le  阅读(466)  评论(0编辑  收藏  举报
重置按钮