【模板】文艺平衡树
題目鏈接
題目描述
您需要寫一種數(shù)據(jù)結(jié)構(gòu)(可參考題目標(biāo)題),來維護(hù)一個(gè)有序數(shù)列。
其中需要提供以下操作:翻轉(zhuǎn)一個(gè)區(qū)間,例如原有序序列是 543215\ 4\ 3\ 2\ 15?4?3?2?1,翻轉(zhuǎn)區(qū)間是 [2,4][2,4][2,4] 的話,結(jié)果是 523415\ 2\ 3\ 4\ 15?2?3?4?1。
輸入格式
第一行兩個(gè)正整數(shù) n,mn,mn,m ,表示序列長度與操作個(gè)數(shù)。序列中第 iii 項(xiàng)初始為 iii。
接下來 mmm 行,每行兩個(gè)正整數(shù) l,rl,rl,r,表示翻轉(zhuǎn)的區(qū)間。
輸出格式
輸出一行 nnn 個(gè)正整數(shù),表示原始序列經(jīng)過 mmm 次變換后的結(jié)果。
輸入輸出樣例
輸入 #1
5 3 1 3 1 3 1 4輸出 #1
4 3 2 1 5說明/提示
對于 100%100\%100% 的數(shù)據(jù),1≤n,m≤105,1≤l≤r≤n1 \le n, m \leq 10^5,1 \le l \le r \le n1≤n,m≤105,1≤l≤r≤n。
Solution
- 模板題。
Code
FHQ Treap
#include<cstdio> #include<cstdlib> #include<algorithm> #include<ctime> using namespace std; const int maxn=1000020; int n,m,root,tot; struct FHQ{int lc,rc;int val,dat,siz,tag; }tr[maxn]; inline int newnode(int v){tr[++tot].siz=1;tr[tot].val=v;tr[tot].dat=rand();return tot; } inline void pushup(int u){tr[u].siz=tr[tr[u].lc].siz+tr[tr[u].rc].siz+1; } inline void pushdown(int u){if(tr[u].tag){swap(tr[u].lc,tr[u].rc);tr[tr[u].lc].tag^=1;tr[tr[u].rc].tag^=1;tr[u].tag=0;} } inline int merge(int x,int y){if(!x||!y)return x+y;pushdown(x),pushdown(y);if(tr[x].dat<tr[y].dat){tr[x].rc=merge(tr[x].rc,y);pushup(x);return x;}else{tr[y].lc=merge(x,tr[y].lc);pushup(y);return y;} } inline void spilt(int u,int k,int &x,int &y){if(!u){x=y=0;return;}pushdown(u);if(k<=tr[tr[u].lc].siz)y=u,spilt(tr[u].lc,k,x,tr[u].lc);elsex=u,spilt(tr[u].rc,k-tr[tr[u].lc].siz-1,tr[u].rc,y);pushup(u); } inline int build(int l,int r){int mid=(l+r)>>1;int u=newnode(mid);if(l<mid)tr[u].lc=build(l,mid-1);if(mid<r)tr[u].rc=build(mid+1,r);pushup(u);return u; } inline void rev(int l,int r){int a,b,c,d;spilt(root,l-1,a,b);spilt(b,r-l+1,c,d);tr[c].tag^=1;root=merge(a,merge(c,d)); } inline void print(int u){pushdown(u);if(tr[u].lc)print(tr[u].lc);if(tr[u].val>=1&&tr[u].val<=n)printf("%d ",tr[u].val);if(tr[u].rc)print(tr[u].rc); } int main(){srand(time(0));scanf("%d%d",&n,&m);root=build(0,n+1);for(int i=1;i<=m;++i){int l,r;scanf("%d%d",&l,&r);rev(l+1,r+1);}print(root);return 0; }Splay
#include<cstdio> #include<algorithm> const int maxn=100010; struct Splay{int val,son[2],fa,tag,siz; }tr[maxn]; int n,m,tot,root; inline void pushup(int u){tr[u].siz=tr[tr[u].son[0]].siz+tr[tr[u].son[1]].siz+1; } inline void pushdown(int u){if(tr[u].tag){tr[tr[u].son[0]].tag^=1;tr[tr[u].son[1]].tag^=1;std::swap(tr[u].son[0],tr[u].son[1]);tr[u].tag=0;} } inline int build(int l,int r,int fa){int u=++tot;int mid=(l+r)>>1;tr[u].val=mid;tr[u].fa=fa;if(l<mid)tr[u].son[0]=build(l,mid-1,u);if(mid<r)tr[u].son[1]=build(mid+1,r,u);pushup(u);return u; } inline void rotate(int x){int y=tr[x].fa,z=tr[y].fa;int k=tr[y].son[1]==x;tr[z].son[tr[z].son[1]==y]=x,tr[x].fa=z;tr[y].son[k]=tr[x].son[k^1],tr[tr[x].son[k^1]].fa=y;tr[x].son[k^1]=y,tr[y].fa=x;pushup(y),pushup(x); } inline void splay(int x,int goal){while(tr[x].fa!=goal){int y=tr[x].fa,z=tr[y].fa;if(z!=goal)tr[y].son[1]==x^tr[z].son[1]==y?rotate(x):rotate(y);rotate(x);}if(!goal)root=x; } inline int ask(int u,int rank){pushdown(u);if(tr[tr[u].son[0]].siz>=rank)return ask(tr[u].son[0],rank);else if(tr[tr[u].son[0]].siz+1==rank)return u;else return ask(tr[u].son[1],rank-tr[tr[u].son[0]].siz-1); } inline void print(int u){pushdown(u);if(tr[u].son[0])print(tr[u].son[0]);if(tr[u].val>=1&&tr[u].val<=n)printf("%d ",tr[u].val);if(tr[u].son[1])print(tr[u].son[1]); } int main(){scanf("%d%d",&n,&m);root=build(0,n+1,0);while(m--){int l,r;scanf("%d%d",&l,&r);l=ask(root,l);r=ask(root,r+2);splay(l,0);splay(r,l);if(tr[r].son[0])tr[tr[r].son[0]].tag^=1;}print(root);return 0; }總結(jié)
- 上一篇: 暑期训练待补
- 下一篇: 微博头条等显示用户IP微博显示头条什么意