二逼平衡树 模板

树套树板子题

我写的是最普通的 外层线段树 套 里层权值$splay$

第一个操作,求$K$在$[L,R]$的排名,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询排名,相加即可,时间$O(log^{2}n)$

第二个操作,求$[L,R]$中排名为$K$的数,二分一个值,到第一个操作里验证,时间$O(log^{3}n)$

第三个操作,单点替换,在线段树里包含$x$的所有区间的$splay$里插入删除即可,时间$O(log^{2}n)$

第四个操作,求$[L,R]$中$K$的前驱,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询前驱,取最大的,时间$O(log^{2}n)$

第五个操作,求$[L,R]$中$K$的后继,在线段树中取出$[L,R]$区间的所有$splay$,每棵$splay$里都查询后继,取最小的,时间$O(log^{2}n)$

线段树套splay还挺暴力的..尤其是第二个操作

人傻常数大,我的代码在洛谷吸氧才能过..

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define N1 50500
  5 #define M1 1105000
  6 #define ll long long
  7 #define dd double
  8 #define inf 2147483647
  9 #define maxn 100000000
 10 using namespace std;
 11 
 12 int gint()
 13 {
 14     int ret=0,fh=1;char c=getchar();
 15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
 16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
 17     return ret*fh;
 18 }
 19 int ret;
 20 struct Splay{
 21 int ch[M1][2],fa[M1],sz[M1],num[M1],val[M1],root[N1<<2],tot;
 22 //inline int idf(int x){return ch[fa[x]][0]==x?0;1;}
 23 inline void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+num[x];}
 24 void rot(int x)
 25 {
 26     int y=fa[x],ff=fa[y],px=ch[fa[x]][0]==x?0:1;
 27     ch[ff][!(ch[fa[y]][0]==y)]=x; fa[x]=ff;
 28     fa[ch[x][px^1]]=y; ch[y][px]=ch[x][px^1]; 
 29     fa[y]=x; ch[x][px^1]=y; 
 30     pushup(y); pushup(x);
 31 }
 32 void splay(int x,int to,int id)
 33 {
 34     if(to==root[id]) root[id]=x;
 35     int y; to=fa[to];
 36     while(fa[x]!=to)
 37     {
 38         y=fa[x];
 39         if(fa[y]==to) rot(x);
 40         else if((ch[fa[x]][0]==x)^(ch[fa[y]][0]==y)) rot(x),rot(x);
 41         else rot(y),rot(x);
 42     }
 43 }
 44 int rank(int id,int w)
 45 {
 46     int x=root[id],p,ans=0;
 47     while(1)
 48     {
 49         if(val[x]==w){ ans+=sz[ch[x][0]]; break;}
 50         p=w<val[x]?0:1;
 51         if(p) ans+=sz[ch[x][0]]+num[x];
 52         if(!ch[x][p]) break;
 53         x=ch[x][p];
 54     }
 55     if(ret&1) splay(x,root[id],id);
 56     return ans;
 57 }
 58 int cre(int w){ tot++; val[tot]=w; sz[tot]=num[tot]=1; return tot;}
 59 void ins(int id,int w)
 60 {
 61     int x=root[id],p;
 62     while(x)
 63     {
 64         if(val[x]==w){ num[x]++; sz[x]++; break; }
 65         p=w<val[x]?0:1;
 66         if(!ch[x][p]){ ch[x][p]=cre(w); fa[ch[x][p]]=x; x=ch[x][p]; break;}
 67         else x=ch[x][p];
 68     }
 69     splay(x,root[id],id);
 70 }
 71 void init(int id){ root[id]=cre(-inf); sz[root[id]]=0; num[root[id]]=0; }
 72 int find(int id,int w)
 73 {
 74     int x=root[id],p;
 75     while(x)
 76     {
 77         if(val[x]==w) break; 
 78         p=w<val[x]?0:1;
 79         if(!ch[x][p]) return 0;
 80         x=ch[x][p];
 81     }
 82     splay(x,root[id],id);
 83     return x;
 84 }
 85 int lower(int id,int w)
 86 {
 87     int x=root[id],ans=-inf,p;
 88     while(1)
 89     {
 90         if(val[x]<w&&val[x]>ans) ans=val[x];
 91         p=w<=val[x]?0:1;
 92         if(!ch[x][p]) break;
 93         x=ch[x][p];
 94     }
 95     if(ret&1) splay(x,root[id],id);
 96     return ans;
 97 }
 98 int upper(int id,int w)
 99 {
100     int x=root[id],ans=inf,p;
101     while(1)
102     {
103         if(val[x]>w&&val[x]<ans) ans=val[x];
104         p=w<val[x]?0:1;
105         if(!ch[x][p]) break;
106         x=ch[x][p];
107     }
108     if(ret&1) splay(x,root[id],id);
109     return ans;
110 }
111 void des(int x){num[x]=sz[x]=ch[x][0]=ch[x][1]=fa[x]=val[x]=0;}
112 void pop(int id,int w)
113 {
114     int x=find(id,w),y; if(!x) return; 
115     if(num[x]>1){ num[x]--; return; }
116     y=ch[x][0]; while(ch[y][1]) y=ch[y][1];
117     fa[ch[x][1]]=y; ch[y][1]=ch[x][1];
118     root[id]=ch[x][0]; des(x);
119     splay(y,root[id],id);
120 }
121 }sp;
122 int a[N1],n,m;
123 struct SEG{
124 void build(int l,int r,int rt)
125 {
126     int i,mid; sp.init(rt);
127     for(i=l;i<=r;i++) sp.ins(rt,a[i]);
128     if(l==r) return; mid=(l+r)>>1; 
129     build(l,mid,rt<<1);
130     build(mid+1,r,rt<<1|1);
131 }
132 int rank(int L,int R,int l,int r,int rt,int w)
133 {
134     if(L<=l&&r<=R){ return sp.rank(rt,w); }
135     int mid=(l+r)>>1,ans=0;
136     if(L<=mid) ans+=rank(L,R,l,mid,rt<<1,w);
137     if(R>mid) ans+=rank(L,R,mid+1,r,rt<<1|1,w);
138     return ans;
139 }
140 int srank(int L,int R,int K)
141 {
142     int l=0,r=maxn,mid,ans=0; K--;
143     while(l<=r){
144         mid=(l+r)>>1;
145         if(rank(L,R,1,n,1,mid)<=K) ans=mid,l=mid+1;
146         else r=mid-1;
147     }return ans;
148 }
149 void update(int x,int l,int r,int rt,int w,int K)
150 {
151     sp.ins(rt,K); sp.pop(rt,w);
152     if(l==r) return;
153     int mid=(l+r)>>1;
154     if(x<=mid) update(x,l,mid,rt<<1,w,K);
155     else update(x,mid+1,r,rt<<1|1,w,K);
156 }
157 void raplace(int x,int K)
158 {
159     update(x,1,n,1,a[x],K);
160     a[x]=K;
161 }
162 int lower(int L,int R,int l,int r,int rt,int w)
163 {
164     if(L<=l&&r<=R){ return sp.lower(rt,w); }
165     int mid=(l+r)>>1,ans=-inf;
166     if(L<=mid) ans=max(ans,lower(L,R,l,mid,rt<<1,w));
167     if(R>mid) ans=max(ans,lower(L,R,mid+1,r,rt<<1|1,w));
168     return ans;
169 }
170 int upper(int L,int R,int l,int r,int rt,int w)
171 {
172     if(L<=l&&r<=R){ return sp.upper(rt,w); }
173     int mid=(l+r)>>1,ans=inf;
174     if(L<=mid) ans=min(ans,upper(L,R,l,mid,rt<<1,w));
175     if(R>mid) ans=min(ans,upper(L,R,mid+1,r,rt<<1|1,w));
176     return ans;
177 }
178 }sg;
179 
180 int main()
181 {
182     scanf("%d%d",&n,&m);
183     int i,j,op,l,r,K,ans;
184     for(i=1;i<=n;i++) a[i]=gint();
185     sg.build(1,n,1);
186     for(i=1;i<=m;i++)
187     {
188         op=gint(); l=gint(); r=gint();
189         switch(op)
190         {
191             case 1:{ K=gint(); ret=sg.rank(l,r,1,n,1,K); printf("%d\n",ret+1); break; }
192             case 2:{ K=gint(); ret=sg.srank(l,r,K); printf("%d\n",ret); break; }
193             case 3:{ sg.raplace(l,r); break; }
194             case 4:{ K=gint(); ret=sg.lower(l,r,1,n,1,K); printf("%d\n",ret); break; }
195             case 5:{ K=gint(); ret=sg.upper(l,r,1,n,1,K); printf("%d\n",ret); break; }
196         }
197     }
198     return 0;
199 }

 

posted @ 2019-01-04 18:26  guapisolo  阅读(175)  评论(0编辑  收藏  举报