bzoj 3196: Tyvj 1730 二逼平衡树
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3196: Tyvj 1730 二逼平衡树相关的知识,希望对你有一定的参考价值。
我操,,,,我记得这个sb题,,搞了一整天,(吐槽,本来开心去洛谷提交,结果不一样,mdzz)
树套树,,,各种套。。。
都是在区间内最基本的查询
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 10 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 11 return x*f; 12 } 13 const int M=3000001; 14 int a[N],pre,tmp,nxt,n,m,sz; 15 int rnd[M],ls[M],rs[M],s[M],v[M],w[M],root[M]; 16 void update(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];} 17 void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;} 18 void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;} 19 void insert(int &k, int num) 20 { 21 if (!k){ 22 k=++sz; s[k]=w[k]=1; ls[k]=rs[k]=0; v[k]=num; rnd[k]=rand(); return; 23 } 24 s[k]++; 25 if (v[k]==num) w[k]++; 26 else if (v[k]>num) {insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k);} 27 else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);} 28 } 29 void del(int &k, int num) 30 { 31 if (v[k]==num) 32 { 33 if (w[k]>1) {w[k]--,s[k]--; return;} 34 else{ 35 if (ls[k]*rs[k]==0) k=ls[k]+rs[k]; 36 else if (rnd[ls[k]]<rnd[rs[k]]) rturn(k),del(k,num); 37 else lturn(k),del(k,num); 38 } 39 } 40 else if (v[k]>num) del(ls[k],num),s[k]--; 41 else del(rs[k],num),s[k]--; 42 } 43 void build(int k, int l, int r, int x, int num) 44 { 45 insert(root[k],num); 46 if (l==r) return; 47 int mid=l+r>>1; 48 if (x<=mid) build(k<<1,l,mid,x,num); 49 else build(k<<1|1,mid+1,r,x,num); 50 } 51 void find_min(int k, int num) 52 { 53 if (!k) return; 54 if (num==v[k]) {tmp+=s[ls[k]]; return;} 55 else if (num<v[k]) find_min(ls[k],num); 56 else tmp+=s[ls[k]]+w[k],find_min(rs[k],num); 57 } 58 void askrank_min(int k, int l, int r, int x, int y, int num) 59 { 60 if (l==x && y==r) {find_min(root[k],num);return;} 61 int mid=l+r>>1; 62 if (y<=mid) askrank_min(k<<1,l,mid,x,y,num); 63 else if (x>mid) askrank_min(k<<1|1,mid+1,r,x,y,num); 64 else askrank_min(k<<1,l,mid,x,mid,num),askrank_min(k<<1|1,mid+1,r,mid+1,y,num); 65 } 66 void change(int k, int l, int r, int pos, int old, int num) 67 { 68 del(root[k],old); insert(root[k],num); 69 if (l==r) return; 70 int mid=l+r>>1; 71 if (pos<=mid) change(k<<1,l,mid,pos,old,num); 72 else change(k<<1|1,mid+1,r,pos,old,num); 73 } 74 void findpre(int k, int num) 75 { 76 if (!k) return; 77 if (v[k]>=num) findpre(ls[k],num); 78 else pre=max(pre,v[k]), findpre(rs[k],num); 79 } 80 void getpre(int k, int l, int r, int x, int y, int num) 81 { 82 if (l==x && y==r) {findpre(root[k],num);return;} 83 int mid=l+r>>1; 84 if (y<=mid) getpre(k<<1,l,mid,x,y,num); 85 else if (x>mid) getpre(k<<1|1,mid+1,r,x,y,num); 86 else getpre(k<<1,l,mid,x,mid,num),getpre(k<<1|1,mid+1,r,mid+1,y,num); 87 } 88 void findnxt(int k, int num) 89 { 90 if (!k) return; 91 if (v[k]<=num) findnxt(rs[k],num); 92 else nxt=min(nxt,v[k]),findnxt(ls[k],num); 93 } 94 void getnxt(int k, int l, int r, int x, int y, int num) 95 { 96 if (l==x && y==r) {findnxt(root[k],num);return;} 97 int mid=l+r>>1; 98 if (y<=mid) getnxt(k<<1,l,mid,x,y,num); 99 else if (x>mid) getnxt(k<<1|1,mid+1,r,x,y,num); 100 else getnxt(k<<1,l,mid,x,mid,num),getnxt(k<<1|1,mid+1,r,mid+1,y,num); 101 } 102 int main() 103 { 104 n=ra(); m=ra(); 105 for (int i=1; i<=n; i++) a[i]=ra(); 106 for (int i=1; i<=n; i++) build(1,1,n,i,a[i]); 107 while (m--) 108 { 109 int opt=ra(); 110 if (opt==1) 111 { 112 int l=ra(),r=ra(),k=ra(); tmp=1; 113 askrank_min(1,1,n,l,r,k); 114 printf("%d\n",tmp); 115 } 116 if (opt==2) 117 { 118 int l=ra(),r=ra(),k=ra(); 119 int x=0,y=1000000005,ans; 120 while (x<=y) 121 { 122 int mid=x+y>>1; 123 tmp=1; askrank_min(1,1,n,l,r,mid); 124 if (tmp<=k) x=mid+1,ans=mid; else y=mid-1; 125 } 126 printf("%d\n",ans); 127 } 128 if (opt==3) 129 { 130 int pos=ra(),k=ra(); 131 change(1,1,n,pos,a[pos],k); 132 a[pos]=k; 133 } 134 if (opt==4) 135 { 136 int l=ra(),r=ra(),k=ra(); pre=-inf; 137 getpre(1,1,n,l,r,k); 138 printf("%d\n",pre); 139 } 140 if (opt==5) 141 { 142 int l=ra(),r=ra(),k=ra(); 143 nxt=inf; 144 getnxt(1,1,n,l,r,k); 145 printf("%d\n",nxt); 146 } 147 // system("pause"); 148 } 149 return 0; 150 }
以上是关于bzoj 3196: Tyvj 1730 二逼平衡树的主要内容,如果未能解决你的问题,请参考以下文章