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 }
View Code

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

4 3 2 1 5

HINT

 



N,M<=100000

 

Source

[Submit][Status][Discuss]
posted @ 2015-07-03 13:48  ChenThree  阅读(104)  评论(0编辑  收藏  举报