首页 > 代码库 > P3391 文艺平衡树
P3391 文艺平衡树
hh
题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入输出格式
输入格式:
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1:
5 31 31 31 4
输出样例#1:
4 3 2 1 5
说明
N,M<=100000
分析
不要问我为什么,我是抄的别人的代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdlib> 7 #include<ctime> 8 using namespace std; 9 const int MAXN=300001; 10 static void read(int &n) 11 { 12 char c=‘+‘;int x=0;bool flag=0; 13 while(c<‘0‘||c>‘9‘){c=getchar();if(c==‘-‘)flag=1;} 14 while(c>=‘0‘&&c<=‘9‘){x=(x<<1)+(x<<3)+(c-48);c=getchar();} 15 flag==1?n=-x:n=x; 16 } 17 int ch[MAXN][3];// 0左孩子 1右孩子 18 int val[MAXN];// 每一个点的权值 19 int pri[MAXN];// 随机生成的附件权值 20 int siz[MAXN];// 以i为节点的树的节点数量 21 int sz;// 总结点的数量 22 int n,m; 23 int x,y,z,a,b,root; 24 int mark[MAXN]; 25 void update(int x) 26 { 27 siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]]; 28 } 29 void pushdown(int x) 30 { 31 if(x&&mark[x]) 32 { 33 mark[x]=0; 34 swap(ch[x][0],ch[x][1]); 35 if(ch[x][0]) mark[ch[x][0]]^=1; 36 if(ch[x][1]) mark[ch[x][1]]^=1; 37 } 38 } 39 int new_node(int v) 40 { 41 siz[++sz]=1;// 新开辟一个节点 42 val[sz]=v; 43 pri[sz]=rand(); 44 return sz; 45 } 46 47 int merge(int x,int y)// 合并 48 { 49 if(!x||!y) return x+y;// x和y中必定有一个是0 50 pushdown(x);pushdown(y); 51 if(pri[x]<pri[y])// 把x加到左边的树上 52 { 53 ch[x][1]=merge(ch[x][1],y);// 不懂的看GIF图 54 update(x); 55 return x; 56 } 57 else 58 { 59 ch[y][0]=merge(x,ch[y][0]); 60 update(y); 61 return y; 62 } 63 } 64 void split(int now,int k,int &x,int &y) 65 { 66 if(!now) x=y=0;// 到达叶子节点 67 else 68 { 69 pushdown(now); 70 if (k<=siz[ch[now][0]]) 71 y=now,split(ch[now][0],k,x,ch[now][0]); 72 else 73 x=now,split(ch[now][1],k-siz[ch[now][0]]-1,ch[now][1],y); 74 update(now); 75 } 76 } 77 int build(int l,int r) 78 { 79 if(l>r) return 0; 80 int mid=(l+r)>>1;int v=mid-1; 81 int now=new_node(v); 82 ch[now][0]=build(l,mid-1); 83 ch[now][1]=build(mid+1,r); 84 update(now); 85 //pushdown(now); 86 return now; 87 } 88 void dfs(int x) 89 { 90 if(!x) return ; 91 pushdown(x); 92 dfs(ch[x][0]); 93 if(val[x]>=1&&val[x]<=n) 94 printf("%d ",val[x]); 95 dfs(ch[x][1]); 96 } 97 void res(int l,int r) 98 { 99 int a,b,c,d;100 split(root,r+1,a,b);101 split(a,l,c,d);102 mark[d]^=1;103 root=merge(merge(c,d),b);104 }105 int main()106 {107 srand((unsigned)time(NULL));108 109 read(n);read(m);110 root=build(1,n+2);111 for(int i=1;i<=m;i++)112 {int l,r;read(l);read(r);res(l,r);}113 dfs(root);114 return 0;115 }
P3391 文艺平衡树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。