hdu 3487 splay

切割的话就split再merge,区间修改就splay然后lazy标记。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5
  6 const int N = 300000;
  7 int ans[N];
  8 int n, m, cnt;
  9
 10 struct Node
 11 {
 12     Node * ch[2];
 13     int val;
 14     int rank;
 15     int sz;
 16     int flip;
 17
 18     int cmp( int x ) const
 19     {
 20         if ( x == rank ) return -1;
 21         return x < rank ? 0 : 1;
 22     }
 23
 24     void maintain()
 25     {
 26         sz = rank = 1;
 27         if ( ch[0] != NULL )
 28         {
 29             sz += ch[0]->sz;
 30             rank += ch[0]->sz;
 31         }
 32         if ( ch[1] != NULL )
 33         {
 34             sz += ch[1]->sz;
 35         }
 36     }
 37
 38     void pushdown()
 39     {
 40         if ( flip )
 41         {
 42             swap( ch[0], ch[1] );
 43             flip = 0;
 44             if ( ch[0] != NULL ) ch[0]->flip ^= 1;
 45             if ( ch[1] != NULL ) ch[1]->flip ^= 1;
 46         }
 47     }
 48 };
 49
 50 void visit( int val )
 51 {
 52     if ( val == 0 || val == n + 1 ) return ;
 53     ans[cnt++] = val;
 54 }
 55
 56 void inorder( Node * o )
 57 {
 58     if ( o == NULL ) return ;
 59     o->pushdown();
 60     inorder( o->ch[0] );
 61     visit( o->val );
 62     inorder( o->ch[1] );
 63 }
 64
 65 void rotate( Node * & o, int d )
 66 {
 67     Node * k = o->ch[d ^ 1];
 68     o->ch[d ^ 1] = k->ch[d];
 69     k->ch[d] = o;
 70     o->maintain();
 71     k->maintain();
 72     o = k;
 73 }
 74
 75 void splay( Node * & o, int k )
 76 {
 77     o->pushdown();
 78     o->maintain();
 79     int d = o->cmp(k);
 80     if ( d != -1 )
 81     {
 82         if ( d == 1 ) k -= o->rank;
 83         Node * p = o->ch[d];
 84         p->pushdown();
 85         p->maintain();
 86         int d2 = p->cmp(k);
 87         if ( d2 != -1 )
 88         {
 89             int k2 = ( d2 == 0 ? k : k - p->rank );
 90             splay( p->ch[d2], k2 );
 91             if ( d == d2 )
 92             {
 93                 rotate( o, d ^ 1 );
 94             }
 95             else
 96             {
 97                 rotate( o->ch[d], d );
 98             }
 99         }
100         rotate( o, d ^ 1 );
101     }
102 }
103
104 Node * build( int l, int r )
105 {
106     if ( l > r ) return NULL;
107     Node * o = new Node();
108     int mid = ( l + r ) >> 1;
109     o->sz = r - l + 1;
110     o->val = mid;
111     o->rank = mid - l + 1;
112     o->flip = 0;
113     o->ch[0] = build( l, mid - 1 );
114     o->ch[1] = build( mid + 1, r );
115     return o;
116 }
117
118 void split( Node * o, int k, Node * & left, Node * & right )
119 {
120     splay( o, k );
121     left = o;
122     right = o->ch[1];
123     o->ch[1] = NULL;
124     left->maintain();
125 }
126
127 Node * merge( Node * left, Node * right )
128 {
129     splay( left, left->sz );
130     left->ch[1] = right;
131     left->maintain();
132     return left;
133 }
134
135 int main ()
136 {
137     while ( scanf("%d%d", &n, &m) != EOF )
138     {
139         if ( n == -1 && m == -1 ) break;
140         Node * root = build( 0, n + 1 );
141         char cmd[11];
142         int a, b, c;
143         while ( m-- )
144         {
145             scanf("%s", cmd);
146             if ( cmd[0] == ‘C‘ )
147             {
148                 scanf("%d%d%d", &a, &b, &c);
149                 Node * left, * mid, * right, * o;
150                 split( root, a, left, o );
151                 split( o, b - a + 1, mid, right );
152                 root = merge( left, right );
153                 split( root, c + 1, left, right );
154                 root = merge( merge( left, mid ), right );
155             }
156             else
157             {
158                 scanf("%d%d", &a, &b);
159                 splay( root, a );
160                 splay( root->ch[1], b + 2 - a );
161                 Node * p = root->ch[1]->ch[0];
162                 p->flip ^= 1;
163             }
164         }
165           cnt = 0;
166         inorder(root);
167         for ( int i = 0; i < n; i++ )
168         {
169             printf("%d", ans[i]);
170             if ( i != n - 1 ) putchar(‘ ‘);
171             else putchar(‘\n‘);
172         }
173     }
174     return 0;
175 }
时间: 2024-10-19 12:25:48

hdu 3487 splay的相关文章

HDU 3487 Splay tree

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6779    Accepted Submission(s): 2678 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamond

HDU 3487 splay区间翻转切割

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3986    Accepted Submission(s): 1633 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamon

hdu 3487 Play with Chain (Splay)

hdu 3487 Splay树模板题 题意: 一开始给出1 2 3 4 ... n 这样一个序列,对这个序列进行以下两种操作: (1)CUT a b c: 将子串[a,b]切下来,放到剩余串的第c个数之后 . (2) FLIP a b : 将子串[a,b]翻转,如 1 2 3 4 就变成 4 3 2 1 . 总之就是一道Splay树的模板题 ... 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm&

hdu 3487 Play with Chain(splay区间剪切,翻转)

题目链接:hdu 3487 Play with Chain 题意: cut a b c: 将a到b区间剪切下来,放在第c位置的后面. flip a b: 翻转a到b区间 题解: 第一个操作,选通过旋转,然后使a到b区间变成根的右儿子的左儿子,然后剪掉. 再找到c+1的位置,接上. 第二个操作,区间标记就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4

hdu 3487 Play with Chain

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform t

hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)

题意:与区间查询点更新,点有20W个,询问区间的最大值.曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多. 第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩.现在只学了一点点.切个点更新试试. 大致思路:用编号(数组)作为树的键值建树,每插一个数,沿路节点更新最大值(每个结点有一个附加信息标记以之为子树的树所有点的最大值).所以,查询时[i,j],只要把i-1伸展到树根,把j+1伸展到I-1下面,那么j+1的左子树就是要的区间了!查该子树根值信息即可(特判端点

HDU 3487:Play with Chain(Splay)

http://acm.hdu.edu.cn/showproblem.php?pid=3487 题意:有两种操作:1.Flip l r ,把 l 到 r 这段区间 reverse.2.Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面. 思路:做完了上一道变态题目,做这道题目如鱼得水.Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回

Splay树——HDU 3487 Play with Chain

对应HDU题目:点击打开链接 Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4571    Accepted Submission(s): 1859 Problem Description YaoYao is fond of playing his chains. He has a chain cont

HDU 3487(Play with Chain-Splay)[template:Splay]

Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4679    Accepted Submission(s): 1892 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamon