[BZOJ3110][Zjoi2013]K大数查询 树套树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3110
我们建一棵权值线段树,并对里面的节点建普通区间线段树,注意动态开点。对于查询就用类似于二分的操作就好了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef unsigned int uint; 6 int inline readint(){ 7 int Num=0,Flag=1;char ch; 8 while((ch=getchar())<'0'||ch>'9') if(ch=='-') break; 9 if(ch=='-') Flag=-1; else Num=ch-'0'; 10 while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0'; 11 return Num*Flag; 12 } 13 void outint(int x){ 14 if(x>=10) outint(x/10); 15 putchar(x%10+'0'); 16 } 17 int n,m,opt,a,b,c; 18 int rt[(50000<<2)+10],lc[20000000],rc[20000000],col[20000000],cnt=0; 19 uint sum[20000000]; 20 void inline Pushup(int &x){ 21 sum[x]=sum[lc[x]]+sum[rc[x]]; 22 } 23 void inline Pushdown(int &x,int l,int r){ 24 if(!col[x]||l==r) return; 25 if(!lc[x]) lc[x]=++cnt; 26 if(!rc[x]) rc[x]=++cnt; 27 col[lc[x]]+=col[x]; 28 col[rc[x]]+=col[x]; 29 uint mid=l+r>>1; 30 sum[lc[x]]+=(mid-l+1)*col[x]; 31 sum[rc[x]]+=(r-mid)*col[x]; 32 col[x]=0; 33 } 34 void Modify(int &x,int l,int r,int L,int R){ 35 if(!x) x=++cnt; 36 if(L<=l&&r<=R){ 37 col[x]++; 38 sum[x]+=r-l+1; 39 return; 40 } 41 Pushdown(x,l,r); 42 int mid=l+r>>1; 43 if(L<=mid) Modify(lc[x],l,mid,L,R); 44 if(R>mid) Modify(rc[x],mid+1,r,L,R); 45 Pushup(x); 46 } 47 uint Qry(int &x,int l,int r,int L,int R){ 48 if(L<=l&&r<=R) return sum[x]; 49 Pushdown(x,l,r); 50 int mid=l+r>>1; 51 uint s=0; 52 if(L<=mid) s=Qry(lc[x],l,mid,L,R); 53 if(R>mid) s+=Qry(rc[x],mid+1,r,L,R); 54 return s; 55 } 56 void Insert(){ 57 int x=1,l=1,r=n; 58 while(l!=r){ 59 int mid=l+r>>1; 60 Modify(rt[x],1,n,a,b); 61 if(c<=mid) r=mid,x<<=1; 62 else l=mid+1,x=x<<1|1; 63 } 64 Modify(rt[x],1,n,a,b); 65 } 66 void Solve(){ 67 int x=1,l=1,r=n; 68 while(l!=r){ 69 int mid=l+r>>1; 70 uint rk=Qry(rt[x<<1|1],1,n,a,b); 71 if(rk>=c) l=mid+1,x=x<<1|1; 72 else r=mid,x<<=1,c-=rk; 73 } 74 outint(l); 75 putchar('\n'); 76 } 77 int main(){ 78 n=readint(); 79 m=readint(); 80 for(int i=1;i<=m;i++){ 81 opt=readint(); 82 a=readint(); 83 b=readint(); 84 c=readint(); 85 if(opt==1) Insert(); 86 else Solve(); 87 } 88 return 0; 89 }