标签:二分 rt return int number lt th POJ2104 op
刚学了整体二分,用这种解法来解决这道题。
首先对于每个询问时可以二分解决的,这也是可以使用整体二分的前提。将原来的序列看成是插入操作,和询问操作和在一起根据值域进行二分。用树状数组来检验二分值。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=100010,INF=1e9; 4 struct node{ 5 int op,x,y,z; 6 }q[N<<1],lq[N<<1],rq[N<<1]; 7 int n,m,t,c[N],ans[N]; 8 9 int lowbit(int x){ 10 return x&(-x); 11 } 12 13 int ask(int x){ 14 int sum=0; 15 while(x){ 16 sum+=c[x]; 17 x-=lowbit(x); 18 } 19 return sum; 20 } 21 22 void change(int x,int y){ 23 while(x<=n){ 24 c[x]+=y; 25 x+=lowbit(x); 26 } 27 } 28 29 void solve(int L,int R,int l,int r){ 30 if(l>r) return ;//操作序列为空 31 if(L==R){ 32 for(int i=l;i<=r;i++){ 33 if(q[i].op>0) ans[q[i].op]=L; 34 } 35 return ; 36 } 37 int mid=(L+R)>>1; 38 int lt=0,rt=0; 39 for(int i=l;i<=r;i++){ 40 if(q[i].op==0){ 41 if(q[i].y<=mid) change(q[i].x,1),lq[++lt]=q[i]; 42 else rq[++rt]=q[i]; 43 } 44 else{ 45 int cnt=ask(q[i].y)-ask(q[i].x-1); 46 if(cnt>=q[i].z) lq[++lt]=q[i]; 47 else q[i].z-=cnt,rq[++rt]=q[i]; 48 } 49 } 50 for(int i=r;i>=l;i--){ 51 if(q[i].op==0 && q[i].y<=mid) change(q[i].x,-1); 52 } 53 for(int i=1;i<=lt;i++) q[l+i-1]=lq[i]; 54 for(int i=1;i<=rt;i++) q[l+lt+i-1]=rq[i]; 55 solve(L,mid,l,l+lt-1); 56 solve(mid+1,R,l+lt,r); 57 } 58 59 int main(){ 60 scanf("%d%d",&n,&m); 61 for(int i=1;i<=n;i++){ 62 int val;scanf("%d",&val); 63 q[++t].op=0,q[t].x=i,q[t].y=val; 64 } 65 for(int i=1;i<=m;i++){ 66 int l,r,k; 67 scanf("%d%d%d",&l,&r,&k); 68 q[++t].op=i,q[t].x=l,q[t].y=r,q[t].z=k; 69 } 70 solve(-INF,INF,1,t); 71 for(int i=1;i<=m;i++) printf("%d\n",ans[i]); 72 return 0; 73 }
标签:二分,rt,return,int,number,lt,th,POJ2104,op 来源: https://www.cnblogs.com/yhxnoerror/p/16483472.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。