sgu187:Twist and whirl -- want to cheat(splay+区间翻转)
来源:互联网 发布:淘宝店铺详情页模板 编辑:程序博客网 时间:2024/06/05 09:46
题意:
裸的区间翻转。
分析:
我们可以ws的用一下stl的reverse,如果手写的话splay较好。
类似线段树lazy思想,我们找到l-1项和r+1项,将其分别splay到root和右孩子,之间夹着的区间我们给其一个翻转。
问题①:找到当前序列中的第k项?
我们需要对每一个结点记录以该结点为根的子树的结点数size,从root出发向做左或向右找。
我们需要在rotate的时候更新size。
问题②:如何翻转?
找到l-1和r+1后,将其夹着的区间的根结点的rev值^1即可。
问题③:何时rev起作用?
Ⅰrotate之前将其传给子结点;
Ⅱ找第k项结点时,每往下走一步时,都要将其传给子结点。
其他的问题应该可以随意脑补了。
#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 130009;int n, m;int f[MAXN], c[MAXN][2];int root;int size[MAXN];bool rev[MAXN];int maketree(int l, int r, int fa){int mid = (l+r)>>1;f[mid] = fa;if(l <= mid-1) c[mid][0] = maketree(l, mid-1, mid);if(mid+1 <= r) c[mid][1] = maketree(mid+1, r, mid);size[mid] = size[c[mid][0]]+size[c[mid][1]]+1;return mid;}void down(int p){if(!rev[p]) return ;rev[p] = 0;swap(c[p][0], c[p][1]);rev[c[p][0]] ^= 1;rev[c[p][1]] ^= 1;}void rotate(int s, int &root){down(s);int x = f[s], y = f[x];int p = (s==c[x][1]), q = p^1;int fp = (x==c[y][1]);if(x == root) root = s;else c[y][fp] = s;size[s] = size[x];size[x] = size[c[s][q]]+size[c[x][q]]+1;f[s] = y;f[x] = s;f[c[s][q]] = x;c[x][p] = c[s][q];c[s][q] = x;}void splay(int p, int &root){while(p != root){int x = f[p], y = f[x];if(x != root){if((c[x][0] == p)==(c[y][0] == x)) rotate(x, root);else rotate(p, root);}rotate(p, root);}}int find(int p){int now = root;while(1){down(now);if(p == size[c[now][0]]+1) break;if(p > size[c[now][0]]) p -= size[c[now][0]]+1, now = c[now][1];else now = c[now][0];}return now;}int main(){scanf("%d%d", &n, &m);root = (1+n+2)>>1;maketree(1, n+2, 0);for(int i = 1, l, r; i <= m; ++i){scanf("%d%d", &l, &r);int x = find(l), y = find(r+2);splay(x, root);splay(y, c[root][1]);rev[c[y][0]] ^= 1;}for(int i = 2; i <= n+1; ++i)printf("%d ", find(i)-1);return 0;}
0 0
- sgu187:Twist and whirl -- want to cheat(splay+区间翻转)
- 【Splay】[SGU 187]Twist and whirl - want to cheat
- sgu 187 Twist and whirl - want to cheat 伸展树(splay)
- UVA 11922 Permutation Transformer && SGU 187. Twist and whirl - want to cheat(伸展树)
- Splay区间翻转
- 区间翻转问题 Splay
- hdu 1890 splay区间翻转
- Splay tree 区间翻转 模板
- HDU 1890 splay区间翻转
- HDU 1890 Splay区间翻转
- hdu 1890 splay 区间翻转
- 【codevs 3303】翻转区间 splay
- BZOJ 3223 Splay区间翻转
- HDU3487(splay区间翻转+区间切割)
- hdu 1890 Splay区间最小值、区间翻转
- hdu 3487 区间 翻转 切割 插入 splay
- 【HDU】1890 Robotic Sort 翻转区间【splay】
- 11922 - Permutation Transformer (Splay区间翻转)
- 黑马程序源——java基础——嵌套类和内部类
- loadrunner必用函数web_reg_save_param获取多个符合边界值条件的使用方法
- HDU 3911 Black And White(线段树区间合并)
- 软件设计模式之工厂模式(jAVA)
- eclipse配置maven老的资源库没法使用问题
- sgu187:Twist and whirl -- want to cheat(splay+区间翻转)
- 大话NodeJS之------Http模块
- SDUT14级队员训练1 D - Periodic Strings
- CSS-浮动篇float
- angularJs利用ng-include搭建最基本的一个包含过滤器、控制器的页面
- UML类图关系和StarUML使用说明
- opengl debug tools
- 感想京东
- 近期生活小结