平衡树系列最后一题
坑啊
10s时间限制跑了9764ms。。。还是要学一学bit套主席树啦。。。
经典的线段树套treap。。。至于第一发为什么要TLE(我不会告诉你treap插入的时候忘了旋转 WOC)
自认为treap写的挺好看的(欢迎来喷)
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 cint inf=100000000; 27 void inin(int &ret) 28 { 29 ret=0;int f=0;char ch=getchar(); 30 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 31 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 32 ret=f?-ret:ret; 33 } 34 int ch[2000050][2],c[2000050],s[2000050],rr[2000050],w[2000020],ed; 35 struct segtree 36 { 37 int l,r,root; 38 segtree(){root=0;} 39 void maintain(int k){if(k)s[k]=c[k]+s[ch[k][0]]+s[ch[k][1]];} 40 void rotate(int &k,int d) 41 { 42 int p=ch[k][d^1]; 43 ch[k][d^1]=ch[p][d]; 44 ch[p][d]=k;s[p]=s[k]; 45 maintain(k),k=p; 46 } 47 private: 48 void add(int &k,const int &x) 49 { 50 if(!k) 51 { 52 k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=1;ch[k][0]=ch[k][1]=0; 53 return ; 54 }s[k]++; 55 if(x==w[k]){c[k]++;return ;} 56 int d=x>w[k];add(ch[k][d],x); 57 if(rr[ch[k][d]]<rr[k])rotate(k,d^1); 58 } 59 bool del(int &k,const int &x) 60 { 61 if(!k)return 0; 62 if(x==w[k]) 63 { 64 if(c[k]>1){c[k]--,s[k]--;return 1;} 65 if(!ch[k][0]){k=ch[k][1];return 1;} 66 if(!ch[k][1]){k=ch[k][0];return 1;} 67 if(rr[ch[k][0]]<rr[ch[k][1]])rotate(k,1); 68 else rotate(k,0); 69 return del(k,x); 70 } 71 int d=x>w[k]; 72 if(del(ch[k][d],x)) 73 { 74 s[k]--; 75 return 1; 76 } 77 else return 0; 78 } 79 int findrank(int k,const int &x) 80 { 81 if(!k)return 0; 82 int pp=(ch[k][0]?s[ch[k][0]]:0); 83 if(x==w[k])return pp; 84 if(x>w[k])return pp+c[k]+findrank(ch[k][1],x); 85 return findrank(ch[k][0],x); 86 } 87 int findwei(int k,const int &x) 88 { 89 if(!k)return 0; 90 int pp=(ch[k][0]?s[ch[k][0]]:0); 91 if(x<=pp)return findwei(ch[k][0],x); 92 if(x>pp+c[k])return findwei(ch[k][1],x-pp-c[k]); 93 return w[k]; 94 95 } 96 void findqian(int k,const int &x,int &ans) 97 { 98 if(!k)return ; 99 if(x>w[k])ans=w[k],findqian(ch[k][1],x,ans); 100 else findqian(ch[k][0],x,ans); 101 } 102 void findhou(int k,const int &x,int &ans) 103 { 104 if(!k)return ; 105 if(x<w[k])ans=w[k],findhou(ch[k][0],x,ans); 106 else findhou(ch[k][1],x,ans); 107 } 108 public: 109 void add(int x){add(root,x);} 110 void del(int x){del(root,x);} 111 int findrank(int x){return findrank(root,x);} 112 int findwei(int x){return findwei(root,x);} 113 int findqian(int x) 114 { 115 int ans=0;findqian(root,x,ans); 116 return ans; 117 } 118 int findhou(int x) 119 { 120 int ans=0;findhou(root,x,ans); 121 return !ans?inf:ans; 122 } 123 }t[200020]; 124 int qi[50050]; 125 void build(int k,int l,int r,int x) 126 { 127 t[k].l=l,t[k].r=r,t[k].add(qi[x]); 128 if(l==r)return ;int mid=(l+r)>>1; 129 if(x<=mid)build(k<<1,l,mid,x); 130 else build(k<<1|1,mid+1,r,x); 131 } 132 int findrank(int k,int l,int r,int x) 133 { 134 if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x); 135 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 136 if(r<=mid)return findrank(p1,l,r,x); 137 if(l>mid)return findrank(p2,l,r,x); 138 return findrank(p1,l,r,x)+findrank(p2,l,r,x); 139 } 140 int findqian(int k,int l,int r,int x) 141 { 142 if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x); 143 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 144 if(r<=mid)return findqian(p1,l,r,x); 145 if(l>mid)return findqian(p2,l,r,x); 146 return max(findqian(p1,l,r,x),findqian(p2,l,r,x)); 147 } 148 int findhou(int k,int l,int r,int x) 149 { 150 if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x); 151 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 152 if(r<=mid)return findhou(p1,l,r,x); 153 if(l>mid)return findhou(p2,l,r,x); 154 return min(findhou(p1,l,r,x),findhou(p2,l,r,x)); 155 } 156 int findwei(int l,int r,int x) 157 { 158 int ll=0,rr=inf,mid,ans; 159 while(ll<=rr) 160 { 161 mid=(ll+rr)>>1; 162 int rank=findrank(1,l,r,mid)+1; 163 if(rank<=x)ans=mid,ll=mid+1;else rr=mid-1; 164 } 165 return findqian(1,l,r,ans+1); 166 } 167 void change(int k,int x,int w) 168 { 169 t[k].del(qi[x]),t[k].add(w); 170 if(t[k].l==t[k].r)return ; 171 int mid=(t[k].l+t[k].r)>>1; 172 if(x<=mid)change(k<<1,x,w); 173 else change(k<<1|1,x,w); 174 } 175 int n,m; 176 int CSC() 177 { 178 freopen("in.in","r",stdin); 179 freopen("out.out","w",stdout); 180 inin(n),inin(m); 181 re(i,1,n)inin(qi[i]); 182 re(i,1,n)build(1,1,n,i); 183 re(i,1,m) 184 { 185 int opt,q,ww,e; 186 inin(opt); 187 if(opt==1) 188 { 189 inin(q),inin(ww),inin(e); 190 printf("%d ",findrank(1,q,ww,e)+1); 191 } 192 else if(opt==2) 193 { 194 inin(q),inin(ww),inin(e); 195 printf("%d ",findwei(q,ww,e)); 196 } 197 else if(opt==3) 198 { 199 inin(q),inin(ww); 200 change(1,q,ww);qi[q]=ww; 201 } 202 else if(opt==4) 203 { 204 inin(q),inin(ww),inin(e); 205 printf("%d ",findqian(1,q,ww,e)); 206 } 207 else 208 { 209 inin(q),inin(ww),inin(e);int ret=findhou(1,q,ww,e); 210 // printf("%d ",ret==inf?0:ret); 211 printf("%d ",ret); 212 } 213 } 214 return 0; 215 }