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(nlogn)。
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; |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析