bzoj3223 splay
区间反转 先发代码 待会再谈感悟
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define rep(i,l,r) for(int i=l;i<r;i++) 7 #define clr(a,x) memset(a,x,sizeof(a)) 8 using namespace std; 9 const int maxn=100005,maxm=100005; 10 int n,m; 11 struct node*null,*pt; 12 struct node{ 13 node*ch[2]; 14 int v,s; 15 bool rev; 16 node(int v1=0):v(v1),s(1),rev(0){ 17 ch[0]=ch[1]=null; 18 } 19 inline int cmp(int k)const{ 20 k-=ch[0]->s; 21 if(k==1) return -1; 22 return k<=0?0:1; 23 } 24 inline void update(){ 25 s=ch[0]->s+ch[1]->s+1; 26 } 27 inline void pushdown(){ 28 if(rev){ 29 rev=0; 30 swap(ch[0],ch[1]); 31 ch[0]->rev^=1; 32 ch[1]->rev^=1; 33 } 34 } 35 void*operator new(size_t){ 36 return pt++; 37 } 38 }; 39 node*root; 40 node x[maxn]; 41 void rotate(node*&o,int d) 42 { 43 node* k=o->ch[d^1]; 44 o->ch[d^1]=k->ch[d]; 45 k->ch[d]=o; 46 o->update(); 47 k->update(); 48 o=k; 49 } 50 void splay(node*&o,int k) 51 { 52 o->pushdown(); 53 int d=o->cmp(k); 54 if(d==-1) return; 55 if(d==1) k-=o->ch[0]->s+1; 56 node*p=o->ch[d]; 57 p->pushdown(); 58 int d2=p->cmp(k); 59 int k2=d2?k-p->ch[0]->s-1:k; 60 if(d2!=-1){ 61 splay(p->ch[d2],k2); 62 d==d2?rotate(o,d^1):rotate(o->ch[d],d); 63 } 64 rotate(o,d^1); 65 } 66 node*build(int l,int r) 67 { 68 if(l>=r) return null; 69 int mid=(l+r)>>1; 70 node*o=new node(mid); 71 if(l<mid) o->ch[0]=build(l,mid); 72 if(r>mid+1) o->ch[1]=build(mid+1,r); 73 o->update(); 74 return o; 75 } 76 void init() 77 { 78 pt=x; 79 null=new node(); 80 null->s=0; 81 root=build(0,n+2); 82 } 83 void dfs(node*o) 84 { 85 if(o==null) return; 86 o->pushdown(); 87 dfs(o->ch[0]); 88 if(o->v>=1&&o->v<=n) printf("%d ",o->v); 89 dfs(o->ch[1]); 90 } 91 int read() 92 { 93 int ans=0,f=1; 94 char c; 95 c=getchar(); 96 while(!isdigit(c)){ 97 if(c=='-') f=-1; 98 c=getchar(); 99 } 100 while(isdigit(c)){ 101 ans=ans*10+c-'0'; 102 c=getchar(); 103 } 104 return f*ans; 105 } 106 int main() 107 { 108 n=read(); 109 m=read(); 110 init(); 111 while(m--){ 112 int l=read(),r=read(); 113 if(l==r) continue; 114 splay(root,l); 115 splay(root->ch[1],r+1-root->ch[0]->s); 116 root->ch[1]->ch[0]->rev^=1; 117 } 118 dfs(root); 119 return 0; 120 }
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1848 Solved: 1026
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000