洛谷P3527 [POI2011]MET-Meteors(整体二分)

传送门

 

整体二分

先二分一个答案,判断是否可行,把可行的全都扔到左边,不可行的扔到右边

判断是否可行用树状数组就行

具体细节看代码好了

整体二分细节真多……也可能是我大脑已经退化了?

 1 //minamoto
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #define ll long long
 7 using namespace std;
 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 9 char buf[1<<21],*p1=buf,*p2=buf;
10 inline ll read(){
11     #define num ch-'0'
12     char ch;bool flag=0;ll res;
13     while(!isdigit(ch=getc()))
14     (ch=='-')&&(flag=true);
15     for(res=num;isdigit(ch=getc());res=res*10+num);
16     (flag)&&(res=-res);
17     #undef num
18     return res;
19 }
20 const int N=700005;
21 int n,m,k,ans[N],mb[N],st[N],top;
22 ll c[N];
23 vector<int> a[N];
24 struct node{
25     int l,r,op,id;ll k;
26     node(){}
27     node(int l,int r,int op,int id,ll k):l(l),r(r),op(op),id(id),k(k){}
28 }q[N],q1[N],q2[N];
29 inline void add(int x,ll y){
30     for(;x<=m;x+=x&-x){
31         if(!c[x]) st[++top]=x;
32         c[x]+=y;
33     }
34 }
35 ll query(int x){
36     ll res=0;
37     for(;x;x-=x&-x) res+=c[x];
38     return res;
39 }
40 void solve(int l,int r,int ql,int qr){
41     if(l>r) return;
42     if(ql==qr){
43         for(int i=l;i<=r;++i) 
44         if(q[i].op==1) ans[q[i].id]=ql;
45         return;
46     }
47     int mid=ql+qr>>1,p1=0,p2=0;
48     for(int i=l;i<=r;++i){
49         switch(q[i].op){
50             case 1:{
51                 ll res=0;
52                 for(int j=0,s=a[q[i].id].size();j<s;++j){
53                     res+=query(a[q[i].id][j]);
54                     if(res>=q[i].k) break;
55                 }
56                 if(res>=q[i].k) q1[++p1]=q[i];
57                 else q[i].k-=res,q2[++p2]=q[i];
58                 break;
59             }
60             case 2:{
61                 if(q[i].id<=mid) add(q[i].l,q[i].k),add(q[i].r+1,-q[i].k),q1[++p1]=q[i];
62                 else q2[++p2]=q[i];
63                 break;
64             }
65             case 3:{
66                 if(q[i].id<=mid) add(1,q[i].k),add(q[i].r+1,-q[i].k),add(q[i].l,q[i].k),q1[++p1]=q[i];
67                 else q2[++p2]=q[i];
68                 break;
69             }
70         }
71     }
72     while(top) c[st[top--]]=0;
73     for(int i=1;i<=p1;++i) q[l+i-1]=q1[i];
74     for(int i=1;i<=p2;++i) q[l+p1+i-1]=q2[i];
75     solve(l,l+p1-1,ql,mid),solve(l+p1,r,mid+1,qr);
76 }
77 int main(){
78 //    freopen("testdata.in","r",stdin);
79     n=read(),m=read();
80     for(int i=1;i<=m;++i) a[read()].push_back(i);
81     for(int i=1;i<=n;++i) mb[i]=read();
82     k=read();
83     for(int i=1,l,r,t;i<=k;++i){
84         l=read(),r=read(),t=read();
85         q[i]=node(l,r,r>=l?2:3,i,t);
86     }
87     for(int i=1;i<=n;++i)
88     q[i+k]=node(0,0,1,i,mb[i]);
89     solve(1,k+n,1,k+1);
90     for(int i=1;i<=n;++i)
91     (ans[i]!=k+1)?printf("%d\n",ans[i]):puts("NIE");
92     return 0;
93 }

 

posted @ 2018-09-10 22:11  bztMinamoto  阅读(134)  评论(0编辑  收藏  举报
Live2D