HDU 5412 CRB and Queries 求区间第k小 CDQ分治+整体二分
2015-09-04 16:05
507 查看
恩。。CDQ分治是个神奇的东西。。其思想基于分治。。可以实现大部分离线的带修改的询问
资料:http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html
资料:http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html
//author: CHC //First Edit Time: 2015-09-04 13:18 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <limits> using namespace std; typedef long long LL; const int MAXN=1e+5 + 1000; const int INF = numeric_limits<int>::max(); const LL LL_INF= numeric_limits<LL>::max(); int C[MAXN],A[MAXN],n,q,ans[MAXN]; void Add(int x,int v){ for(int i=x;i<=n;i+=i&-i)C[i]+=v; } int Sum(int x){ int cnt=0; for(int i=x;i>0;i-=i&-i)cnt+=C[i]; return cnt; } struct point { int x,y,k,kind,qpos,delta,cur; point(){} point(int _x,int _y,int _k,int _kind,int _qpos,int _delta,int _cur):x(_x),y(_y),k(_k),kind(_kind),qpos(_qpos),delta(_delta),cur(_cur){} }cs[MAXN<<2],ql[MAXN<<2],qr[MAXN<<2]; int tmp[MAXN<<2]; void cdq(int L,int R,int l,int r){ if(L>R)return ; //printf("L:%d R:%d\n",L,R); //printf("l:%d r:%d\n",l,r); //system("pause"); if(l==r){ for(int i=L;i<=R;i++) if(cs[i].kind==1)ans[cs[i].qpos]=l; //printf("l:%d\n",l); return; } int mid=(l+r)>>1; for(int i=L;i<=R;i++){ if(cs[i].kind==0&&cs[i].y<=mid)Add(cs[i].x,cs[i].delta); else if(cs[i].kind==1)tmp[i]=Sum(cs[i].y)-Sum(cs[i].x-1); } for(int i=L;i<=R;i++) if(cs[i].kind==0&&cs[i].y<=mid)Add(cs[i].x,-cs[i].delta); int totl=0,totr=0; for(int i=L;i<=R;i++){ if(cs[i].kind==1){ //printf("%d %d %d %d\n",mid,cs[i].qpos,cs[i].cur+tmp[i],cs[i].k); if(cs[i].cur+tmp[i]>=cs[i].k){ ql[totl++]=cs[i]; //printf("<<%d %d l:%d tot:%d %d %d %d\n",L,R,mid,cs[i].qpos,cs[i].x,cs[i].y,cs[i].k); } else { cs[i].cur+=tmp[i]; qr[totr++]=cs[i]; //printf(">>%d %d r:%d tot:%d %d %d %d\n",L,R,mid,cs[i].qpos,cs[i].x,cs[i].y,cs[i].k); } } else { if(cs[i].y<=mid)ql[totl++]=cs[i]; else qr[totr++]=cs[i]; } } for(int i=0;i<totl;i++)cs[L+i]=ql[i]; for(int i=0;i<totr;i++)cs[L+totl+i]=qr[i]; //printf("%d %d %d %d-%d %d %d %d\n",L,totl-1,l,mid,L+totl,R,mid+1,r); cdq(L,L+totl-1,l,mid); cdq(L+totl,R,mid+1,r); } int main() { while(~scanf("%d",&n)){ int tot=0; memset(C,0,sizeof(C)); memset(tmp,0,sizeof(tmp)); for(int i=1;i<=n;i++){ scanf("%d",&A[i]); cs[tot++]=point(i,A[i],0,0,0,1,0); } int qtot=0; scanf("%d",&q); for(int i=0,tp,l,r,x;i<q;i++){ scanf("%d",&tp); if(tp==1){ scanf("%d%d",&l,&x); cs[tot++]=point(l,A[l],0,0,0,-1,0); A[l]=x; cs[tot++]=point(l,A[l],0,0,0,1,0); } else { scanf("%d%d%d",&l,&r,&x); cs[tot++]=point(l,r,x,1,qtot++,0,0); } } cdq(0,tot-1,0,1000000000+100); for(int i=0;i<qtot;i++) printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- hdu 5324 树套树、cdq分治
- 1752. [BOI2007]摩基亚Mokia (cdq分治模板题)
- hdu 5126 stars(三维空间cdq分治)
- 【分治】 BZOJ 1176 [Balkan2007]Mokia
- [BZOJ2244][SDOI2011]拦截导弹(DP+CDQ分治)
- HDU - 5730 CDQ分治 + FFT
- HDU - 1166 CDQ分治
- cogs 1752. [BOI2007]摩基亚Mokia
- hdu 1166 敌兵布阵(cdq分治)
- 对CDQ分治的一些见解
- [BZOJ1176][[Balkan2007]Mokia][CDQ分治]
- hdu5618Jam's problem again (CDQ分治)
- HDU1166 敌兵布阵 线段树||树状数组||CDQ分治 入门题复习
- bzoj 2726: [SDOI2012]任务安排
- hdu 5956 The Elder 2016ACM/ICPC沈阳赛区现场赛I
- bzoj 3237: [Ahoi2013]连通图
- codeforces 601E. A Museum Robbery
- bzoj 4237: 稻草人
- BZOJ 1176: [Balkan2007]Mokia (CDQ分治)
- BZOJ 3262: 陌上花开 (CDQ分治)