日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【模板】文艺平衡树

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【模板】文艺平衡树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

題目描述

您需要寫一種數據結構(可參考題目標題),來維護一個有序數列。

其中需要提供以下操作:翻轉一個區間,例如原有序序列是 543215\ 4\ 3\ 2\ 15?4?3?2?1,翻轉區間是 [2,4][2,4][2,4] 的話,結果是 523415\ 2\ 3\ 4\ 15?2?3?4?1

輸入格式

第一行兩個正整數 n,mn,mn,m ,表示序列長度與操作個數。序列中第 iii 項初始為 iii
接下來 mmm 行,每行兩個正整數 l,rl,rl,r,表示翻轉的區間。

輸出格式

輸出一行 nnn 個正整數,表示原始序列經過 mmm 次變換后的結果。

輸入輸出樣例

輸入 #1

5 3 1 3 1 3 1 4

輸出 #1

4 3 2 1 5

說明/提示

對于 100%100\%100% 的數據,1≤n,m≤105,1≤l≤r≤n1 \le n, m \leq 10^5,1 \le l \le r \le n1n,m1051lrn


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

總結

以上是生活随笔為你收集整理的【模板】文艺平衡树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。