文艺平衡术
Posted Hzoi_Maple
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文艺平衡术相关的知识,希望对你有一定的参考价值。
问题 D: Tyvj 1729 文艺平衡树
题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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次变换后的结果
样例输入
5 3
1 3
1 3
1 4
样例输出
4 3 2 1 5
提示
啊啊啊O(≧口≦)O,我上树啦~~然而我恐高( ⊙ o ⊙ )啊!,好像重回空气清新的地面。。
附两份Splay的代码,一个是指针的,一个是数组的。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=100010; 7 int n,m,x,y; 8 struct Splay{ 9 int l[N],r[N],k[N],s[N],root; 10 bool tag[N]; 11 int build(int L,int R){ 12 if(L>R) return 0; 13 int mid=(L+R)>>1; 14 s[mid]=R-L+1; 15 l[mid]=build(L,mid-1); 16 r[mid]=build(mid+1,R); 17 return mid; 18 } 19 void pushdown(int x){ 20 if(tag[x]){ 21 swap(l[x],r[x]); 22 tag[l[x]]^=1;tag[r[x]]^=1; 23 tag[x]^=1; 24 } 25 } 26 void update(int x){ 27 s[x]=s[l[x]]+s[r[x]]+1; 28 } 29 void l_rot(int &x){ 30 int y=r[x]; 31 r[x]=l[y];l[y]=x; 32 update(x);update(y); 33 x=y; 34 } 35 void r_rot(int &x){ 36 int y=l[x]; 37 l[x]=r[y];r[y]=x; 38 update(x);update(y); 39 x=y; 40 } 41 void splay(int &x,int k){ 42 pushdown(x); 43 int i=s[l[x]]+1; 44 if(k==i) return; 45 if(k<i) splay(l[x],k),r_rot(x); 46 else splay(r[x],k-i),l_rot(x); 47 48 } 49 void Swap(int L,int R){ 50 splay(root,L); 51 splay(root,R+2); 52 tag[r[l[root]]]^=1; 53 } 54 void search(int x){ 55 if(!x) return; 56 pushdown(x); 57 search(l[x]); 58 if(k[x]) printf("%d ",k[x]); 59 search(r[x]); 60 } 61 }T; 62 inline int read(){ 63 int sum=0;char ch=getchar(); 64 while(ch<‘0‘||ch>‘9‘) ch=getchar(); 65 while(ch>=‘0‘&&ch<=‘9‘){sum=sum*10+ch-‘0‘;ch=getchar();} 66 return sum; 67 } 68 int main(){ 69 freopen("sph.in","r",stdin); 70 freopen("sph.out","w",stdout); 71 n=read();m=read(); 72 for(int i=1;i<=n;++i) 73 T.k[i+1]=i; 74 T.root=T.build(1,n+2); 75 for(int i=1;i<=m;++i){ 76 x=read();y=read(); 77 T.Swap(x,y); 78 } 79 T.search(T.root); 80 // while(1); 81 return 0; 82 }
这个是数组的。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=100005; 7 int n,m,num,x,y; 8 int read(){ 9 int sum=0,f=1;char ch=getchar(); 10 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1;ch=getchar();} 11 while(ch>=‘0‘&&ch<=‘9‘) {sum=sum*10+ch-‘0‘;ch=getchar();} 12 return sum*f; 13 } 14 struct Splay{ 15 int num,size;bool tag; 16 Splay *fa,*ch[2]; 17 void pushup(){ 18 size=ch[0]->size+ch[1]->size+1; 19 } 20 bool get(){ 21 return fa->ch[0]==this?0:1; 22 } 23 void set(Splay*,int); 24 }pool[N],*null,*root; 25 void Splay::set(Splay *child,int wh){ 26 ch[wh]=child; 27 if(child!=null) child->fa=this; 28 pushup(); 29 return; 30 } 31 Splay* newnode(int x){ 32 Splay *t=&pool[++num]; 33 t->ch[0]=t->ch[1]=null; 34 t->num=x;t->size=1;t->tag=false; 35 return t; 36 } 37 Splay* build(int l,int r,Splay *now){ 38 if(l>r) return null; 39 int mid=(l+r)>>1; 40 Splay *t=newnode(mid); 41 t->fa=now; 42 t->ch[0]=build(l,mid-1,t); 43 t->ch[1]=build(mid+1,r,t); 44 t->pushup(); 45 return t; 46 } 47 void pushdown(Splay *now){ 48 if(now->tag){ 49 swap(now->ch[0],now->ch[1]); 50 if(now->ch[0]!=null) now->ch[0]->tag^=1; 51 if(now->ch[1]!=null) now->ch[1]->tag^=1; 52 now->tag^=1; 53 } 54 } 55 Splay *kth(int k){ 56 Splay *now=root; 57 while(now!=null){ 58 pushdown(now); 59 if(now->ch[0]->size+1==k) return now; 60 if(now->ch[0]->size+1>k) now=now->ch[0]; 61 else k-=now->ch[0]->size+1,now=now->ch[1]; 62 } 63 return null; 64 } 65 Splay *find(int v){ 66 Splay *now=root; 67 int left=0; 68 while(now!=null){ 69 pushdown(now); 70 int tt=left+now->ch[0]->size; 71 if(v==tt+1) return now; 72 if(tt+1>v) now=now->ch[0]; 73 else left=tt+1,now=now->ch[1]; 74 } 75 } 76 void rotate(Splay *&now){ 77 Splay *pa=now->fa; 78 Splay *ga=pa->fa; 79 if(ga->tag) pushdown(ga); 80 if(pa->tag) pushdown(pa); 81 if(now->tag) pushdown(now); 82 int wz=now->get(); 83 pa->set(now->ch[wz^1],wz);now->set(pa,wz^1); 84 now->fa=ga; 85 if(ga!=null) ga->ch[ga->ch[1]==pa]=now; 86 } 87 void splay(Splay *now,Splay *lim){ 88 for(;now->fa!=lim;rotate(now)) 89 if(now->fa->fa!=lim) 90 now->get()==now->fa->get()?rotate(now->fa):rotate(now); 91 if(lim==null) root=now; 92 } 93 void Swap(int x,int y){ 94 Splay *t=kth(x); 95 splay(t,null); 96 t=kth(y+2); 97 splay(t,root); 98 root->ch[1]->ch[0]->tag^=1; 99 } 100 void search(Splay *now){ 101 if(!now) return; 102 pushdown(now); 103 search(now->ch[0]); 104 if(now!=null&&now->num&&now->num!=n+1) 105 printf("%d ",now->num); 106 search(now->ch[1]); 107 } 108 int main(){ 109 freopen("sph.in","r",stdin); 110 freopen("sph.out","w",stdout); 111 n=read();m=read(); 112 null=newnode(-1); 113 null->size=0; 114 root=newnode((n+1)/2); 115 root->fa=null;int mid=(n+1)>>1; 116 root->ch[0]=build(0,mid-1,root); 117 root->ch[1]=build(mid+1,n+1,root); 118 root->pushup(); 119 for(int i=1;i<=m;++i){ 120 x=read();y=read(); 121 Swap(x,y); 122 } 123 search(root); 124 return 0; 125 }
这个是指针的。。。
希望大家一定要学好啊!!!(不要像我)’
N,M<=100000
以上是关于文艺平衡术的主要内容,如果未能解决你的问题,请参考以下文章