Solution Set - Splay
A[洛谷P3369]维护集合,支持插入,删除,查询\(x\)的排名,查询排名\(x\)的数,查询前驱,查询后继。
B[洛谷P3391]维护一个序列,支持区间翻转。
C[洛谷P3380]维护数列,支持单点修改,在某区间内查询\(x\)的排名,排名为\(x\)的数,前驱,后继。
D[洛谷P4036]维护一个字符串,支持单点修改,单点插入,询问两端后缀的最长公共前缀。
E[洛谷P4309]依次将\(1,2,...,n\)插入一个数列中,询问每次插入后的LIS。
F[洛谷P2042]维护一个数列,支持单点插入,区间删除,区间覆盖,区间翻转,查询区间和,查询最大子串和。
G[POJ3580]维护一个数列,支持区间加,区间翻转,区间轮换,单点插入,单点删除,查询区间最小值。
H[洛谷P3215]维护一个括号序列,支持区间覆盖,区间翻转,区间取反,查询将某个区间变为合法至少需要修改的括号数。
I[洛谷P3224]维护一张图,支持连边,查询与某个点连通的点中的第\(k\)小点权。
Splay:伸展树,是一种二叉搜索树,基本操作为旋转和伸展(即将某个点旋转到根)。均摊\(O(n\log n)\)。
Splay相当灵活,常用的处理手段是把点\(l-1\)转到根,再把\(r+1\)转到\(l-1\)的右儿子,此时\(r+1\)的左儿子代表区间\([l,r]\)。
在此基础上,可以像线段树一样用儿子更新信息,打懒惰标记。
A平衡树模板。
B使用懒标记的模板。注意在维护下标的平衡树,在平衡树的中序遍历中位于第\(k\)位的点就代表数列中第\(k\)个数。
C线段树套平衡树,在线段树的每个点开平衡树记录该区间的所有数。
D平衡树维护字符串哈希值,只需要修改push_up即可。询问时二分。
E注意到每次插入不影响已插入的点的DP值,故直接维护即可。
F,G都是懒标记,注意每次提取区间,打标记之后都要push_up。求最大子串和可以维护前缀最大和后缀最大。
H记录把()看做匹配,左边留下的)数和右边留下的(数,以及取反之后的结果,Splay维护即可。
I平衡树的启发式合并。
点击查看A题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=1e9;
int n;
struct Splay{
int rt,tot,fa[N],ch[N][2],val[N],cnt[N],siz[N];
void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+cnt[p];}
bool get(int p){return p==ch[fa[p]][1];}
void clear(int p){fa[p]=ch[p][0]=ch[p][1]=val[p]=cnt[p]=siz[p]=0;}
void rotate(int x){
int y=fa[x],z=fa[y],op=1-get(x);
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
void ins(int v){
if(!tot){rt=tot=1;val[1]=v;cnt[1]=siz[1]=1;return;}
int p=rt,f=0;
while(1){
if(val[p]==v){++cnt[p];++siz[p];push_up(f);splay(p);break;}
f=p;p=ch[p][val[p]<v];
if(!p){
val[p=++tot]=v;cnt[p]=siz[p]=1;
fa[tot]=f;ch[f][val[f]<v]=p;
push_up(f);splay(p);break;
}
}
}
bool find(int v){
int p=rt;
while(p){
if(val[p]==v){splay(p);return true;}
p=ch[p][val[p]<v];
}return false;
}
void merge(int x,int y){
while(ch[x][1])x=ch[x][1];
splay(x);ch[x][1]=y;fa[y]=x;push_up(x);
}
void del(int v){
if(!find(v))return;
if(cnt[rt]>1){--cnt[rt],--siz[rt];return;}
int x=ch[rt][0],y=ch[rt][1];
fa[x]=fa[y]=0;clear(rt);
if(!x||!y){rt=x+y;return;}
merge(x,y);
}
int rank(int v){
find(v);
return siz[ch[rt][0]]+1;
}
int kth(int k){
int p=rt;
while(1){
if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
else{
k-=cnt[p]+siz[ch[p][0]];
if(k<=0){splay(p);return val[p];}
p=ch[p][1];
}
}
}
int nxt(int x,int op){
ins(x);int p=ch[rt][op^1];
if(!p)return -1;
while(ch[p][op])p=ch[p][op];
int res=val[p];del(x);
return res;
}
}cst;
int main(){
scanf("%d",&n);
cst.ins(INF);cst.ins(-INF);
for(int i=1,op,x;i<=n;i++){
scanf("%d%d",&op,&x);
if(op==1)cst.ins(x);
if(op==2)cst.del(x);
if(op==3)printf("%d\n",cst.rank(x)-1);
if(op==4)printf("%d\n",cst.kth(x+1));
if(op==5)printf("%d\n",cst.nxt(x,1));
if(op==6)printf("%d\n",cst.nxt(x,0));
}
return 0;
}
点击查看B题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,ans[N],cnt;
struct Splay{
int rt,tot,fa[N],ch[N][2],val[N],tag[N],siz[N];
void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
int build(int l,int r){
if(l==r){push_up(l);return l;}
int p=l+r>>1;
if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
push_up(p);
return p;
}
bool get(int p){return p==ch[fa[p]][1];}
void push_down(int p){
if(!tag[p])return;
tag[ch[p][0]]^=1;tag[ch[p][1]]^=1;
tag[p]=0;swap(ch[p][0],ch[p][1]);
}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int kth(int k){
int p=rt;
while(1){
push_down(p);
if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
else{
k-=siz[ch[p][0]]+1;
if(k<=0)return p;
p=ch[p][1];
}
}
}
void update(int l,int r){
l=kth(l-1);splay(l,0);
r=kth(r+1);splay(r,l);
tag[ch[r][0]]^=1;
}
void dfs(int p){
push_down(p);
if(ch[p][0])dfs(ch[p][0]);
if(p!=1&&p!=n+2)printf("%d ",p-1);
if(ch[p][1])dfs(ch[p][1]);
}
}cst;
int main(){
scanf("%d%d",&n,&m);
cst.rt=cst.build(1,n+2);
for(int i=1,l,r;i<=m;i++){
scanf("%d%d",&l,&r);
cst.update(l+1,r+1);
}
cst.dfs(cst.rt);
return 0;
}
点击查看C题代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5,M=2.22e7+5,INF=2147483647;
int n,m,a[N];
struct Splay{
int rt[N*10],tot,fa[M],ch[M][2],val[M],cnt[M],siz[M];
void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+cnt[p];}
bool get(int p){return p==ch[fa[p]][1];}
void clear(int p){fa[p]=ch[p][0]=ch[p][1]=val[p]=cnt[p]=siz[p]=0;}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int id,int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt[id]=x;
}
void ins(int id,int v){
if(!rt[id]){rt[id]=++tot;val[tot]=v;cnt[tot]=siz[tot]=1;return;}
int p=rt[id],f=0;
while(1){
if(val[p]==v){++cnt[p];++siz[p];push_up(f);splay(id,p);break;}
f=p;p=ch[p][val[p]<v];
if(!p){
val[p=++tot]=v;cnt[p]=siz[p]=1;
fa[p]=f;ch[f][val[f]<v]=p;
push_up(f);splay(id,p);break;
}
}
}
bool find(int id,int v){
int p=rt[id];
while(1){
if(val[p]==v){splay(id,p);return true;}
p=ch[p][val[p]<v];
}return false;
}
void merge(int id,int x,int y){
while(ch[x][1])x=ch[x][1];
splay(id,x);ch[x][1]=y;fa[y]=x;push_up(x);
}
void del(int id,int v){
if(!find(id,v))return;
if(cnt[rt[id]]>1){--cnt[rt[id]];--siz[rt[id]];return;}
int x=ch[rt[id]][0],y=ch[rt[id]][1];
fa[x]=fa[y]=0;clear(rt[id]);
if(!x||!y)rt[id]=x+y;else merge(id,x,y);
}
int rank(int id,int v){
int p=rt[id],res=0;
while(p){
if(v<val[p])p=ch[p][0];
else{
res+=siz[ch[p][0]];
if(v==val[p]){splay(id,p);return res;}
res+=cnt[p];p=ch[p][1];
}
}
return res;
}
int nxt(int id,int v,int op){
ins(id,v);int p=ch[rt[id]][op^1];
if(!p){del(id,v);return op?-INF:INF;}
while(ch[p][op])p=ch[p][op];
int res=val[p];splay(id,p);del(id,v);
return res;
}
}cst;
struct SegmentTree{
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void modify(int p,int l,int r,int x,int v,int op){
if(!op)cst.del(p,v);else cst.ins(p,v);
if(l==r)return;
if(x<=mid)modify(ls,l,mid,x,v,op);
else modify(rs,mid+1,r,x,v,op);
}
int query_rank(int p,int l,int r,int L,int R,int v){
if(l>=L&&r<=R)return cst.rank(p,v);
if(R<=mid)return query_rank(ls,l,mid,L,R,v);
if(L>mid)return query_rank(rs,mid+1,r,L,R,v);
return query_rank(ls,l,mid,L,R,v)+query_rank(rs,mid+1,r,L,R,v);
}
int query_kth(int L,int R,int k){
int l=0,r=1e8,res=0;
while(l<=r){
int MID=mid;
if(query_rank(1,1,n,L,R,MID)>k)r=MID-1;
else l=MID+1,res=MID;
}
return res;
}
int query_nxt(int p,int l,int r,int L,int R,int v,int op){
if(l>=L&&r<=R)return cst.nxt(p,v,op);
if(R<=mid)return query_nxt(ls,l,mid,L,R,v,op);
if(L>mid)return query_nxt(rs,mid+1,r,L,R,v,op);
return op?max(query_nxt(ls,l,mid,L,R,v,op),query_nxt(rs,mid+1,r,L,R,v,op)):
min(query_nxt(ls,l,mid,L,R,v,op),query_nxt(rs,mid+1,r,L,R,v,op));
}
}seg;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",a+i),seg.modify(1,1,n,i,a[i],1);
for(int i=1,op,l,r,x;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",seg.query_rank(1,1,n,l,r,x)+1);
}
if(op==2){
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",seg.query_kth(l,r,x-1));
}
if(op==3){
scanf("%d%d",&l,&x);
seg.modify(1,1,n,l,a[l],0);a[l]=x;
seg.modify(1,1,n,l,a[l],1);
}
if(op==4){
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",seg.query_nxt(1,1,n,l,r,x,1));
}
if(op==5){
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",seg.query_nxt(1,1,n,l,r,x,0));
}
}
return 0;
}
点击查看D题代码
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=1e5+5;
int n,m,x,y;char s[N],op[3],ch[3];ull r[N],base=131;
struct Splay{
int rt,tot,fa[N],ch[N][2],siz[N];ull val[N],h[N];
void push_up(int p){
h[p]=h[ch[p][0]]+val[p]*r[siz[ch[p][0]]]+h[ch[p][1]]*r[siz[ch[p][0]]+1];
siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
}
bool get(int p){return p==ch[fa[p]][1];}
void clear(int p){fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=h[p]=0;}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int build(int l,int r){
int mid=l+r>>1;val[mid]=s[mid];
if(l<mid)fa[ch[mid][0]=build(l,mid-1)]=mid;
if(r>mid)fa[ch[mid][1]=build(mid+1,r)]=mid;
push_up(mid);return mid;
}
int find(int x){
int p=rt;
while(1){
if(siz[ch[p][0]]>=x)p=ch[p][0];
else if(siz[ch[p][0]]==x-1)return p;
else x-=siz[ch[p][0]]+1,p=ch[p][1];
}
}
ull query(int l,int r){
l=find(l-1);splay(l);r=find(r+1);splay(r,l);
return h[ch[r][0]];
}
void modify(int x,char c){splay(find(x));val[rt]=c;push_up(rt);}
void ins(int x,char c){
int l=find(x);splay(l);int r=find(x+1);splay(r,l);
ch[ch[rt][1]][0]=++tot;fa[tot]=ch[rt][1];val[tot]=h[tot]=c;
splay(tot);
}
}cst;
int main(){
r[0]=1;for(int i=1;i<N;i++)r[i]=r[i-1]*base;
scanf("%s",s+2);n=strlen(s+2);
cst.rt=cst.build(1,n+2);cst.tot=n+2;
scanf("%d",&m);
while(m--){
scanf("%s",op);
if(op[0]=='Q'){
scanf("%d%d",&x,&y);
int l=1,r=min(n-x+1,n-y+1),res=0;
while(l<=r){
int mid=l+r>>1;
if(cst.query(x+1,x+mid)==cst.query(y+1,y+mid))
res=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",res);
}
if(op[0]=='R'){scanf("%d",&x);scanf("%s",ch);cst.modify(x+1,ch[0]);}
if(op[0]=='I'){scanf("%d",&x);scanf("%s",ch);++n;cst.ins(x+1,ch[0]);}
}
return 0;
}
点击查看E题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,ans;
struct Splay{
int rt,tot,fa[N],ch[N][2],siz[N],mx[N],dp[N];
void init(){rt=1;tot=2;ch[1][1]=2;fa[2]=1;siz[1]=2;siz[2]=1;}
void push_up(int p){
mx[p]=max(max(mx[ch[p][0]],mx[ch[p][1]]),dp[p]);
siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int kth(int k){
int p=rt;
while(1){
if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
else{
k-=siz[ch[p][0]]+1;
if(k<=0)return p;
p=ch[p][1];
}
}
}
void update(int x){
int l=kth(x+1);splay(l);
int r=kth(x+2);splay(r,l);
ch[r][0]=++tot;fa[tot]=r;siz[tot]=1;splay(tot);
dp[rt]=mx[ch[rt][0]]+1;
printf("%d\n",ans=max(ans,dp[rt]));
}
}cst;
int main(){
scanf("%d",&n);cst.init();
for(int i=1,x;i<=n;i++){scanf("%d",&x);cst.update(x);}
return 0;
}
//
点击查看F题代码
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
const int N=3e6+5,INF=1e9;
int n,m,a[N];char opt[15];
struct Splay{
int rt,tot,fa[N],ch[N][2],siz[N];
int tag[N],tag2[N],val[N],sum[N],lmx[N],rmx[N],mx[N]={-INF};
void clear(int p){
fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=0;
tag[p]=sum[p]=0;tag2[p]=lmx[p]=rmx[p]=mx[p]=-INF;
}
void push_up(int p){
siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
if(siz[p]==1){sum[p]=lmx[p]=rmx[p]=mx[p]=val[p];return;}
sum[p]=sum[ch[p][0]]+sum[ch[p][1]]+val[p];
lmx[p]=max(lmx[ch[p][0]],sum[ch[p][0]]+val[p]+max(0,lmx[ch[p][1]]));
rmx[p]=max(rmx[ch[p][1]],sum[ch[p][1]]+val[p]+max(0,rmx[ch[p][0]]));
mx[p]=max(max(mx[ch[p][0]],mx[ch[p][1]]),
max(rmx[ch[p][0]],0)+val[p]+max(lmx[ch[p][1]],0));
}
void push_down(int p){
int lc=ch[p][0],rc=ch[p][1];
if(tag2[p]!=-INF){
int v=tag2[p];tag2[p]=-INF;
if(lc)tag2[lc]=val[lc]=v,sum[lc]=siz[lc]*v,
lmx[lc]=rmx[lc]=mx[lc]=v<=0?v:siz[lc]*v;
if(rc)tag2[rc]=val[rc]=v,sum[rc]=siz[rc]*v,
lmx[rc]=rmx[rc]=mx[rc]=v<=0?v:siz[rc]*v;
}
if(tag[p]){
if(lc)tag[lc]^=1,swap(ch[lc][0],ch[lc][1]),swap(lmx[lc],rmx[lc]);
if(rc)tag[rc]^=1,swap(ch[rc][0],ch[rc][1]),swap(lmx[rc],rmx[rc]);
tag[p]=0;
}
}
int build(int l,int r){
if(l==r){val[l]=a[l];tag2[l]=-INF;push_up(l);return l;}
int p=l+r>>1;val[p]=a[p];tag2[p]=-INF;
if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
push_up(p);return p;
}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int kth(int k){
int p=rt;
while(1){
push_down(p);
if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
else{k-=siz[ch[p][0]]+1;if(k<=0)return p;p=ch[p][1];}
}
}
void ins(int p,int v){
int x=kth(p),y=kth(p+1);
splay(x);splay(y,x);
ch[y][0]=++tot;fa[tot]=y;tag2[tot]=-INF;
val[tot]=v;push_up(tot);splay(tot);
}
void range(int&l,int&r){
l=kth(l);r=kth(r+2);
splay(l);splay(r,l);
push_up(r);push_up(l);
}
void del(int l,int r){range(l,r);clear(ch[r][0]);ch[r][0]=0;}
void update1(int l,int r){
range(l,r);int p=ch[r][0];tag[p]^=1;
swap(ch[p][0],ch[p][1]);swap(lmx[p],rmx[p]);
}
void update2(int l,int r,int v){
range(l,r);int p=ch[r][0];
tag2[p]=val[p]=v;sum[p]=siz[p]*v;
lmx[p]=rmx[p]=mx[p]=v<=0?v:siz[p]*v;
}
int query(int l,int r){range(l,r);return sum[ch[r][0]];}
int maxsum(int l,int r){range(l,r);return mx[ch[r][0]];}
}cst;
int main(){
n=read();m=read();
for(int i=2;i<=n+1;i++)a[i]=read();
cst.rt=cst.build(1,n+2);cst.tot=n+2;
while(m--){
scanf("%s",opt);
if(opt[2]=='S'){
int p=read()+1,k=read();n+=k;
while(k--)cst.ins(p,read()),++p;
}
if(opt[2]=='L'){
int p=read(),k=read();n-=k;
if(k)cst.del(p,p+k-1);
}
if(opt[2]=='K'){
int p=read(),k=read(),c=read();
if(k)cst.update2(p,p+k-1,c);
}
if(opt[2]=='V'){
int p=read(),k=read();
if(k)cst.update1(p,p+k-1);
}
if(opt[2]=='T'){
int p=read(),k=read();
if(k)printf("%d\n",cst.query(p,p+k-1));else printf("0\n");
}
if(opt[2]=='X')printf("%d\n",cst.maxsum(1,n));
}
return 0;
}
点击查看G题代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
const int N=2e5+5,INF=1e9;
int n,m,a[N];char opt[15];
struct Splay{
int rt,tot,fa[N],ch[N][2],siz[N];
int tag[N],tag2[N],val[N],mn[N];
void clear(int p){
fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=0;
tag[p]=tag2[p]=0;mn[p]=INF;
}
void push_up(int p){
siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
mn[p]=min(min(mn[ch[p][0]],mn[ch[p][1]]),val[p]);
}
void push_down(int p){
int lc=ch[p][0],rc=ch[p][1];
if(tag2[p]){
int v=tag2[p];tag2[p]=0;
if(lc)val[lc]+=v,mn[lc]+=v,tag2[lc]+=v;
if(rc)val[rc]+=v,mn[rc]+=v,tag2[rc]+=v;
}
if(tag[p]){
if(lc)tag[lc]^=1,swap(ch[lc][0],ch[lc][1]);
if(rc)tag[rc]^=1,swap(ch[rc][0],ch[rc][1]);
tag[p]=0;
}
}
int build(int l,int r){
if(l==r){val[l]=a[l];push_up(l);return l;}
int p=l+r>>1;val[p]=a[p];
if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
push_up(p);return p;
}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int kth(int k){
int p=rt;
while(1){
push_down(p);
if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
else{k-=siz[ch[p][0]]+1;if(k<=0)return p;p=ch[p][1];}
}
}
void ins(int p,int v){
int x=kth(p),y=kth(p+1);
splay(x);splay(y,x);
ch[y][0]=++tot;fa[tot]=y;
val[tot]=v;push_up(tot);splay(tot);
}
void range(int&l,int&r){
l=kth(l);r=kth(r+2);
splay(l);splay(r,l);
push_up(r);push_up(l);
}
void del(int l,int r){range(l,r);clear(ch[r][0]);ch[r][0]=0;}
void move(int l,int r,int t){
int len=r-l+1;t=(t%len+len)%len;if(!t)return;
int x=l,y=r-t;range(x,y);int p=ch[y][0];ch[y][0]=fa[p]=0;push_up(y);
x=l+t;y=l+t-1;range(x,y);ch[y][0]=p;fa[p]=y;push_up(y);
}
void update1(int l,int r){
range(l,r);int p=ch[r][0];tag[p]^=1;
swap(ch[p][0],ch[p][1]);
}
void update2(int l,int r,int v){
range(l,r);int p=ch[r][0];
tag2[p]+=v;val[p]+=v;mn[p]+=v;
}
int query(int l,int r){range(l,r);return mn[ch[r][0]];}
void print(int p){
push_down(p);
if(ch[p][0])print(ch[p][0]);
printf("%d ",val[p]);
if(ch[p][1])print(ch[p][1]);
}
}cst;
int main(){
n=read();cst.mn[0]=INF;
for(int i=2;i<=n+1;i++)a[i]=read();
cst.rt=cst.build(1,n+2);cst.tot=n+2;
m=read();
while(m--){
scanf("%s",opt);
if(opt[0]=='A'){int l=read(),r=read(),c=read();cst.update2(l,r,c);}
if(opt[0]=='R'&&opt[3]=='E'){int l=read(),r=read();cst.update1(l,r);}
if(opt[0]=='R'&&opt[3]=='O'){int l=read(),r=read(),t=read();cst.move(l,r,t);}
if(opt[0]=='I'){int p=read(),v=read();cst.ins(p+1,v);}
if(opt[0]=='D'){int p=read();cst.del(p,p);}
if(opt[0]=='M'){int l=read(),r=read();printf("%d\n",cst.query(l,r));}
}
return 0;
}
点击查看H题代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m;char s[N],opt[10],ch[3];
struct Splay{
int rt,fa[N],ch[N][2],siz[N],val[N];
int lef[N][2],rig[N][2],tag1[N],tag2[N],tag3[N];
void push_up(int p){
int lc=ch[p][0],rc=ch[p][1],l1,r1,l2,r2;
siz[p]=siz[lc]+siz[rc]+1;
l1=lef[lc][0];r1=rig[lc][0];l2=lef[rc][0];r2=rig[rc][0];
if(val[p]==-1)++r1;if(val[p]==1)++l2;
lef[p][0]=l1+l2-min(r1,l2);rig[p][0]=r1+r2-min(r1,l2);
l1=lef[lc][1];r1=rig[lc][1];l2=lef[rc][1];r2=rig[rc][1];
if(val[p]==-1)++l2;if(val[p]==1)++r1;
lef[p][1]=l1+l2-min(r1,l2);rig[p][1]=r1+r2-min(r1,l2);
}
void tag(int p,int op){
if(op==2){
tag2[p]^=1;swap(ch[p][0],ch[p][1]);
swap(lef[p][0],rig[p][1]);swap(lef[p][1],rig[p][0]);
}
else if(op==3){
tag3[p]^=1;val[p]=-val[p];
swap(lef[p][0],lef[p][1]);swap(rig[p][0],rig[p][1]);
}
else{
tag1[p]=val[p]=op;tag3[p]=0;
lef[p][0]=rig[p][1]=(val[p]==1?siz[p]:0);
rig[p][0]=lef[p][1]=(val[p]==1?0:siz[p]);
}
}
void push_down(int p){
int lc=ch[p][0],rc=ch[p][1];
if(tag1[p]){if(lc)tag(lc,tag1[p]);if(rc)tag(rc,tag1[p]);tag1[p]=0;}
if(tag2[p]){tag2[p]=0;if(lc)tag(lc,2);if(rc)tag(rc,2);}
if(tag3[p]){tag3[p]=0;if(lc)tag(lc,3);if(rc)tag(rc,3);}
}
int build(int l,int r){
if(l>r)return 0;
int p=l+r>>1;if(s[p]=='(')val[p]=-1;if(s[p]==')')val[p]=1;
ch[p][0]=build(l,p-1);if(ch[p][0])fa[ch[p][0]]=p;
ch[p][1]=build(p+1,r);if(ch[p][1])fa[ch[p][1]]=p;
push_up(p);return p;
}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int x,int goal=0){
for(int p=fa[x];p!=goal;p=fa[x]){
if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
rotate(x);
}if(!goal)rt=x;
}
int kth(int k){
int p=rt;
while(1){
push_down(p);
if(siz[ch[p][0]]>=k)p=ch[p][0];
else if(siz[ch[p][0]]+1==k)return p;
else k-=siz[ch[p][0]]+1,p=ch[p][1];
}
}
void range(int&l,int&r){l=kth(l);r=kth(r+2);splay(l);splay(r,l);}
void update(int l,int r,int op){
range(l,r);tag(ch[r][0],op);
push_up(r);push_up(l);
}
int query(int l,int r){
range(l,r);int p=ch[r][0];
return (lef[p][0]+rig[p][0])/2+(lef[p][0]&1);
}
}cst;
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+2);
cst.rt=cst.build(1,n+2);
for(int i=1,l,r;i<=m;i++){
scanf("%s",opt);scanf("%d%d",&l,&r);
if(opt[0]=='R'){scanf("%s",ch);cst.update(l,r,ch[0]=='('?-1:1);}
if(opt[0]=='S')cst.update(l,r,2);
if(opt[0]=='I')cst.update(l,r,3);
if(opt[0]=='Q')printf("%d\n",cst.query(l,r));
}
return 0;
}
点击查看I题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,q;char op[3];
int rt[N],len[N],b[N],tot,fa[N*60],ch[N*60][2],val[N*60][2],siz[N*60];
void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
int y=fa[x],z=fa[y],op=get(x)^1;
ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
push_up(y);push_up(x);
}
void splay(int id,int x){
for(int p=fa[x];p;p=fa[x]){
if(fa[p])rotate(get(p)==get(x)?p:x);
rotate(x);
}rt[id]=x;
}
void ins(int id,int v,int w){
b[w]=id;++len[id];
if(!rt[id]){
rt[id]=++tot;siz[tot]=1;
val[tot][0]=v;val[tot][1]=w;
return;
}
int p=rt[id],f=0;
while(1){
f=p;p=ch[p][val[p][0]<v];
if(!p){
val[p=++tot][0]=v;val[p][1]=w;siz[p]=1;
fa[p]=f;ch[f][val[f][0]<v]=p;
push_up(f);splay(id,p);break;
}
}
}
void merge(int p,int id){
ins(id,val[p][0],val[p][1]);
if(ch[p][0])merge(ch[p][0],id);
if(ch[p][1])merge(ch[p][1],id);
}
int kth(int id,int k){
int p=rt[id];
while(1){
if(siz[ch[p][0]]>=k)p=ch[p][0];
else{
k-=siz[ch[p][0]]+1;
if(k<=0){splay(id,p);return val[p][1];}
p=ch[p][1];
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,x;i<=n;i++){scanf("%d",&x);ins(i,x,i);}
for(int i=1,x,y;i<=m;i++){
scanf("%d%d",&x,&y);
if(len[b[x]]<len[b[y]])swap(x,y);
merge(rt[b[y]],b[x]);
}
scanf("%d",&q);
for(int i=1,x,y;i<=q;i++){
scanf("%s",op);scanf("%d%d",&x,&y);
if(op[0]=='Q'){
if(len[b[x]]<y)printf("-1\n");
else printf("%d\n",kth(b[x],y));
}
else{
if(len[b[x]]<len[b[y]])swap(x,y);
merge(rt[b[y]],b[x]);
}
}
return 0;
}