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;
}

Solution Set - Splay的更多相关文章

  1. NOIP 2017 列队 - Splay - 树状数组

    题目传送门 传送点I 传送点II 题目大意 (家喻户晓的题目应该不需要大意) (我之前咋把NOIP 2017打成了NOIP 2018,好绝望) Solution 1 Splay 每行一颗Splay,没 ...

  2. 【BZOJ-2329&2209】括号修复&括号序列 Splay

    2329: [HNOI2011]括号修复 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1007  Solved: 476[Submit][Statu ...

  3. BZOJ1014:[JSOI2008]火星人(Splay,hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

  4. SPOJ 3273

    传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 Treap 版 //SPOJ 3273 //by Cydiater //2016.8.31 #include < ...

  5. [HDU1890]RoboticSort

    Problem 每次找到最小值,然后把它和它前面的数翻转,然后找第二小数······ 然后输出这些数的下标. Solution 用splay维护,每次找到最小值,然后翻转前面区间. Notice 细节 ...

  6. [BZOJ3678]wangxz与OJ-[Splay一类的平衡树]

    Description 传送门 Solution 直接splay搞定吧..似乎非旋treap也ok? 我已经菜到模板题都写不出来了qaq Code #include<iostream> # ...

  7. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

  8. 【BZOJ-3786】星系探索 Splay + DFS序

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 647  Solved: 212[Submit][Status][Discuss] ...

  9. 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 806  Solved: 329[Submit][ ...

  10. 【BZOJ-1014】火星人prefix Splay + 二分 + Hash

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5852  Solved: 1871[Submit] ...

随机推荐

  1. KingbaseES kdb_database_link客户端字符集导致的乱码问题

    前言 关于我们经常见到的字符集乱码问题,很可能因为数据库服务器端的操作系统字符集和客户端字符集不一致导致的. 当我们通过kdb_database_link插件访问oracle数据库出现乱码,只需要调整 ...

  2. Games101:作业6

    说明 本次作业主要实现对上一次作业代码的重构以及使用BVH加速求交的交点判断和递归调用 代码框架的修改 有影响的改动就是框架中定义了两个结构体一个是光线ray,一个是交点Intersection 交点 ...

  3. 使用OHOS SDK构建assimp

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone https://github.com/assimp/assimp.git 进入源码 ...

  4. WCHAR 字符串拼接

    LPCWSTR GetIniPath() { WCHAR buffer[MAX_PATH]; BOOL result = SHGetSpecialFolderPath(0, buffer, CSIDL ...

  5. Launching Teamviewer remotely through SSH

    Launching Teamviewer remotely through SSH When you need to manage your Server remotely, but you can ...

  6. JS isPrototypeOf 和hasOwnProperty 还有in的区别

    isPrototypeOf 和hasOwnProperty 的区别 isPrototypeOf 是判断原生链上是否有该对象. 1.isPrototypeOf isPrototypeOf是用来判断指定对 ...

  7. leetcode:3. 无重复字符的最长子串

    3. 无重复字符的最长子串 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3  解释: 因为无重复字符的最长子 ...

  8. 对中间件概念的理解,如何封装 node 中间件

    一.是什么 中间件(Middleware)是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享.功能共享的目的 在 ...

  9. dojo\dart脚本编程语言

    Dojo是一个用于构建高效.可扩展的Web应用程序的开源JavaScript框架.它提供了一系列功能丰富的模块和组件,包括DOM操作.事件处理.异步编程.动画效果等.Dojo还具有强大的用户界面(UI ...

  10. k8s集群部署1.28.2版本(无坑)

    Kubernetes-1.28.2 集群介绍及搭建 一.Kubernetes 概述 1.什么是Kubernetes? K8S 的全称为 Kubernetes.用于自动部署.扩展和管理"容器化 ...