hdu4453Looploop(splay)
2013-10-10 20:16
531 查看
题目请戳这里
题目大意:给一个数字串,长度n,首尾相连的。有一个对序列操作的指针,初始指向第一个数字。给m个操作,2个参数k1,k2。给6种操作:
1:add x,在当前指针所在位置顺时针方向的k2个数字,每个数字加x。
2:reverse,从当前指针所在位置开始顺时针方向k1个数字翻转。
3:insert x,当前指针下一个位置加上一个x。
4:delete,删除当前指针所在位置元素。
5:move x,x=1的时候指针逆时针移动一个位置,x=2的时候指针顺时针移动一个位置。
6:query,查询当前指针所指的元素值。
题目的插图也很明白。
题目分析:splay的基本操作。具体实现:
1,每个节点维护一个累加值,延时标记。
2,每个节点维护一个翻转标记,延时标记。因为是环状的,所以可能要分2部分,解决方法是如果尾部不够,将序列头部剪切一段到尾部,凑齐再翻转。
3,略
4,删除很简单,注意删除后记得检查指针位置是否合法,因为是环状的,可能要移动到序列最左端。
5,略
6,。。。
代码又写的比较长,将就着看吧=_=!!。。。。
详情请见代码:
题目大意:给一个数字串,长度n,首尾相连的。有一个对序列操作的指针,初始指向第一个数字。给m个操作,2个参数k1,k2。给6种操作:
1:add x,在当前指针所在位置顺时针方向的k2个数字,每个数字加x。
2:reverse,从当前指针所在位置开始顺时针方向k1个数字翻转。
3:insert x,当前指针下一个位置加上一个x。
4:delete,删除当前指针所在位置元素。
5:move x,x=1的时候指针逆时针移动一个位置,x=2的时候指针顺时针移动一个位置。
6:query,查询当前指针所指的元素值。
题目的插图也很明白。
题目分析:splay的基本操作。具体实现:
1,每个节点维护一个累加值,延时标记。
2,每个节点维护一个翻转标记,延时标记。因为是环状的,所以可能要分2部分,解决方法是如果尾部不够,将序列头部剪切一段到尾部,凑齐再翻转。
3,略
4,删除很简单,注意删除后记得检查指针位置是否合法,因为是环状的,可能要移动到序列最左端。
5,略
6,。。。
代码又写的比较长,将就着看吧=_=!!。。。。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1000005; const int inf = 0x3f3f3f3f; int next[N + N]; struct node { int l,r,f,add,lazy,key,size; }tree[N + N]; int n,m,k1,k2; void init() { tree[0].size = tree[0].l = tree[0].r = tree[0].f = 0; tree[0].add = tree[0].key = tree[0].lazy = 0; int nn = N + N; for(int i = 0;i < nn;i ++) next[i] = i + 1; } int newnode() { int p = next[0]; next[0] = next[p]; tree[p].lazy = tree[p].add = 0; tree[p].l = tree[p].r = tree[p].f = 0; tree[p].size = 1; return p; } void delnode(int p) { next[p] = next[0]; next[0] = p; } void pushup(int rt) { if(rt) { tree[rt].size = tree[tree[rt].l].size + tree[tree[rt].r].size + 1; } } void pushdown(int rt) { if(!rt) return; int ls = tree[rt].l; int rs = tree[rt].r; if(tree[rt].add) { if(ls) { tree[ls].add += tree[rt].add; tree[ls].key += tree[rt].add; } if(rs) { tree[rs].add += tree[rt].add; tree[rs].key += tree[rt].add; } tree[rt].add = 0; } if(tree[rt].lazy) { swap(tree[rt].l,tree[rt].r); if(ls) tree[ls].lazy ^= 1; if(rs) tree[rs].lazy ^= 1; tree[rt].lazy = 0; } } void zig(int x) { int p = tree[x].f; pushdown(p); pushdown(x); tree[p].l = tree[x].r; if(tree[x].r) tree[tree[x].r].f = p; pushup(p); tree[x].r = p; tree[x].f = tree[p].f; pushup(x); tree[p].f = x; if(tree[x].f == 0) return; if(tree[tree[x].f].l == tree[x].r) tree[tree[x].f].l = x; else tree[tree[x].f].r = x; } void zag(int x) { int p = tree[x].f; pushdown(p); pushdown(x); tree[p].r = tree[x].l; if(tree[x].l) tree[tree[x].l].f = p; pushup(p); tree[x].l = p; tree[x].f = tree[p].f; pushup(x); tree[p].f = x; if(tree[x].f == 0) return; if(tree[tree[x].f].l == tree[x].l) tree[tree[x].f].l = x; else tree[tree[x].f].r = x; } int splay(int x,int goal) { pushdown(x); int p; while(tree[x].f != goal) { p = tree[x].f; int g = tree[p].f; if(g == goal) { if(tree[p].l == x) zig(x); if(tree[p].r == x) zag(x); } else { if(tree[g].l == p && tree[p].l == x) zig(p),zig(x); else if(tree[g].l == p && tree[p].r == x) zag(x),zig(x); else if(tree[g].r == p && tree[p].r == x) zag(p),zag(x); else if(tree[g].r == p && tree[p].l == x) zig(x),zag(x); } } pushup(x); return x; } int build(int s,int e,int fa) { if(s > e) return 0; int mid = (s + e)>>1; int p = newnode(); tree[p].l = build(s,mid - 1,p); scanf("%d",&tree[p].key); tree[p].f = fa; tree[p].r = build(mid + 1,e,p); pushup(p); return p; } int getmin(int rt) { pushdown(rt); while(tree[rt].l) { rt = tree[rt].l; pushdown(rt); } return rt; } int getmax(int rt) { pushdown(rt); while(tree[rt].r) { rt = tree[rt].r; pushdown(rt); } return rt; } int find(int pos,int rt) { if(!rt) return 0; pushdown(rt); if(tree[tree[rt].l].size == pos - 1) return rt; if(tree[tree[rt].l].size >= pos) return find(pos,tree[rt].l); else return find(pos - tree[tree[rt].l].size - 1,tree[rt].r); } void prepare(int &root) { root = newnode(); tree[root].key = inf; tree[root].r = newnode(); tree[tree[root].r].key = inf; tree[tree[root].r].f = root; tree[tree[root].r].l = build(1,n,tree[root].r); pushup(tree[root].r); pushup(root); int tmp = getmin(tree[tree[root].r].l); root = splay(tmp,0); } void Rotate_interval(int a,int b,int &root) { int l = find(a,root); int r = find(b + 2,root); root = splay(l,0); tree[root].r = splay(r,root); pushup(tree[root].r); pushup(root); } void Add(int x,int &root) { int rt,a,b,lefta = 0; rt = root; if(tree[tree[root].r].size < k2) lefta = k2 - tree[tree[root].r].size; if(lefta) { a = tree[tree[root].l].size; b = tree[root].size - 2; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].add += x; tree[tree[tree[root].r].l].key += x; a = 1; b = a + lefta - 1; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].add += x; tree[tree[tree[root].r].l].key += x; } else { a = tree[tree[root].l].size; b = a + k2 - 1; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].add += x; tree[tree[tree[root].r].l].key += x; } root = splay(rt,0); } void Reverse(int &root) { int a,b,rt,lefta = 0; int lsize = tree[tree[root].l].size; if(tree[tree[root].r].size < k1) lefta = k1 - tree[tree[root].r].size; if(lefta) { a = 1; b = lefta; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].lazy ^= 1; a = lefta + 1; b = tree[root].size - 2; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].lazy ^= 1; a = 1;b = tree[root].size - 2; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].lazy ^= 1; } a = lsize - lefta; b = a + k1 - 1; Rotate_interval(a,b,root); tree[tree[tree[root].r].l].lazy ^= 1; rt = find(lsize - lefta + 1,root); root = splay(rt,0); } void Insert(int x,int &root) { int a = getmin(tree[root].r); tree[root].r = splay(a,root); int p = newnode(); tree[p].key = x; tree[p].f = tree[root].r; tree[tree[root].r].l = p; pushup(tree[root].r); pushup(root); } void Delete(int &root) { int a = getmin(tree[root].r); tree[root].r = splay(a,root); int p = root; tree[tree[root].r].f = 0; tree[tree[root].l].f = tree[root].r; tree[tree[root].r].l = tree[root].l; root = tree[root].r;delnode(p); if(tree[root].r == 0) { a = find(2,root); root = splay(a,0); } pushup(root); } void Move(int x,int &root) { int tmp; if(x == 1) { if(tree[tree[root].l].size > 1) tmp = getmax(tree[root].l); else tmp = find(tree[root].size - 1,root); } else { if(tree[tree[root].r].size > 1) tmp = getmin(tree[root].r); else tmp = find(2,root); } root = splay(tmp,0); } void Query(int &root) { printf("%d\n",tree[root].key); } int main() { int x,cas = 0; int root; char op[20]; init(); while(scanf("%d",&n),n) { scanf("%d%d%d",&m,&k1,&k2); prepare(root); printf("Case #%d:\n",++cas); while(m --) { scanf("%s",op); switch(*op) { case 'a':scanf("%d",&x);Add(x,root);break; case 'r':Reverse(root);break; case 'i':scanf("%d",&x);Insert(x,root);break; case 'd':Delete(root);break; case 'm':scanf("%d",&x);Move(x,root);break; case 'q':Query(root);break; } } } return 0; } //218MS 14960K
相关文章推荐
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- Java数据结构之简单链表的定义与实现方法示例
- qqwry.dat的数据结构图文解释第1/2页
- Java数据结构之双端链表原理与实现方法
- Huffman 编码压缩算法
- C 的反思穷究链表
- 数据结构&算法学习
- 第二话:数据结构的历史与来由
- 第一话:你的数据结构怎么学的?
- 鸟瞰数据结构的知识点全貌
- 数据结构的基本概念和术语
- 开发语言、开发工具、数据结构和算法的关系
- 排序算法总结
- CC数据结构学习.0
- PHP常用函数
- [转]可视化的数据结构和算法
- PHP数据结构预热:PHP的迭代器
- C语言实现各类排序算法
- vector list两种不同的容器