HDU 4453 Looploop (伸展树splay tree)
Looploop
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 781 Accepted Submission(s): 220
The figure above shows a Looploop of 6 elments. Let's assuming the preset parameter k1 is 3, and k2 is 4.
XXX can do six operations with the toy.
1: add x
Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.
2: reverse
Starting from the arrow pointed element, reverse the first k1 clockwise elements.
3: insert x
Insert a new element with number x to the right (along clockwise) of the arrow pointed element.
4: delete
Delete the element the arrow pointed and then move the arrow to the right element.
5: move x
x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.
6: query
Output the number on the arrow pointed element in one line.
XXX wants to give answers to every query in a serial of operations.
For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤105, M≤105) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy.
Second line contains N integers ai(-104≤ai≤104) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning.
Then m lines follow, each line contains one of the six operations described above.
It is guaranteed that the "x" in the "add","insert" and "move" operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations.
The input ends with a line of 0 0 0 0.
3 4 5 6 7
query
5 13 2 4
1 2 3 4 5
move 2
query
insert 8
reverse
query
add 2
query
move 1
query
move 1
query
delete
query
0 0 0 0
3
Case #2:
2
8
10
1
5
1
用splay tree解决很容易实现。
- /* ***********************************************
- Author :kuangbin
- Created Time :2013-10-22 16:10:40
- ************************************************ */
- #include <stdio.h>
- #include <string.h>
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <set>
- #include <map>
- #include <string>
- #include <math.h>
- #include <stdlib.h>
- #include <time.h>
- using namespace std;
- #define Key_value ch[ch[root][1]][0]
- const int MAXN = ;
- int pre[MAXN],ch[MAXN][],key[MAXN],size[MAXN];
- int root,tot1;
- int s[MAXN],tot2;
- int rev[MAXN],add[MAXN];
- int n,q,k1,k2;
- int a[MAXN];
- int tp;//指针
- void NewNode(int &r,int father,int k)
- {
- if(tot2)r = s[tot2--];
- else r = ++tot1;
- pre[r] = father;
- ch[r][] = ch[r][] = ;
- key[r] = k;
- add[r] = ;
- rev[r] = ;
- size[r] = ;
- }
- void Update_Rev(int r)
- {
- if(!r)return;
- swap(ch[r][],ch[r][]);
- rev[r] ^= ;
- }
- void Update_ADD(int r,int ADD)
- {
- if(!r)return;
- key[r] += ADD;
- add[r] += ADD;
- }
- void push_up(int r)
- {
- size[r] = size[ch[r][]] + size[ch[r][]] + ;
- }
- void push_down(int r)
- {
- if(add[r])
- {
- Update_ADD(ch[r][],add[r]);
- Update_ADD(ch[r][],add[r]);
- add[r] = ;
- }
- if(rev[r])
- {
- Update_Rev(ch[r][]);
- Update_Rev(ch[r][]);
- rev[r] = ;
- }
- }
- void Build(int &x,int l,int r,int father)
- {
- if(l > r)return;
- int mid = (l+r)/;
- NewNode(x,father,a[mid]);
- Build(ch[x][],l,mid-,x);
- Build(ch[x][],mid+,r,x);
- push_up(x);
- }
- void Init()
- {
- root = tot1 = tot2 = ;
- ch[root][] = ch[root][] = size[root] = pre[root] = ;
- rev[root] = ;
- add[root] = ;
- NewNode(root,,-);
- NewNode(ch[root][],root,-);
- for(int i = ;i < n;i++)
- scanf("%d",&a[i]);
- Build(Key_value,,n-,ch[root][]);
- push_up(ch[root][]);
- push_up(root);
- }
- //旋转,0为左旋,1为右旋
- void Rotate(int x,int kind)
- {
- int y = pre[x];
- push_down(y);
- push_down(x);
- ch[y][!kind] = ch[x][kind];
- pre[ch[x][kind]] = y;
- if(pre[y])
- ch[pre[y]][ch[pre[y]][]==y] = x;
- pre[x] = pre[y];
- ch[x][kind] = y;
- pre[y] = x;
- push_up(y);
- }
- void Splay(int r,int goal)
- {
- push_down(r);
- while(pre[r] != goal)
- {
- if(pre[pre[r]] == goal)
- {
- push_down(pre[r]);
- push_down(r);
- Rotate(r,ch[pre[r]][] == r);
- }
- else
- {
- push_down(pre[pre[r]]);
- push_down(pre[r]);
- push_down(r);
- int y = pre[r];
- int kind = ch[pre[y]][]==y;
- if(ch[y][kind] == r)
- {
- Rotate(r,!kind);
- Rotate(r,kind);
- }
- else
- {
- Rotate(y,kind);
- Rotate(r,kind);
- }
- }
- }
- push_up(r);
- if(goal == ) root = r;
- }
- int Get_kth(int r,int k)
- {
- push_down(r);
- int t = size[ch[r][]] + ;
- if(t == k)return r;
- if(t > k)return Get_kth(ch[r][],k);
- else return Get_kth(ch[r][],k-t);
- }
- void ADD(int x)
- {
- //先搬移动
- Splay(tp,);
- int tmp = size[ch[root][]] + ;
- Splay(Get_kth(root,),);
- Splay(Get_kth(root,tmp),root);
- tmp = Key_value;
- Key_value = ;
- push_up(ch[root][]);
- push_up(root);
- Splay(Get_kth(root,size[root] - ),);
- Key_value = tmp;
- pre[Key_value] = ch[root][];
- push_up(ch[root][]);
- push_up(root);
- Splay(Get_kth(root,),);
- Splay(Get_kth(root,k2+),root);
- Update_ADD(Key_value,x);
- push_up(ch[root][]);
- push_up(root);
- tp = Get_kth(root,);
- }
- void REVERSE()
- {
- Splay(tp,);
- int tmp = size[ch[root][]] + ;
- Splay(Get_kth(root,),);
- Splay(Get_kth(root,tmp),root);
- tmp = Key_value;
- Key_value = ;
- push_up(ch[root][]);
- push_up(root);
- Splay(Get_kth(root,size[root] - ),);
- Key_value = tmp;
- pre[Key_value] = ch[root][];
- push_up(ch[root][]);
- push_up(root);
- Splay(Get_kth(root,),);
- Splay(Get_kth(root,k1+),root);
- Update_Rev(Key_value);
- push_up(ch[root][]);
- push_up(root);
- tp = Get_kth(root,);
- }
- void INSERT(int x)
- {
- Splay(tp,);
- //printf("%d %d\n",tp,size[ch[root][0]]+2);
- int tt = Get_kth(root,size[ch[root][]]+);
- //printf("%d %d %d\n",Get_kth(root,size[ch[root][0]]+2),tt,key[tt]);
- Splay(Get_kth(root,size[ch[root][]]+),root);
- NewNode(Key_value,ch[root][],x);
- push_up(ch[root][]);
- push_up(root);
- }
- void DELETE()
- {
- Splay(tp,);
- int tmp = size[ch[root][]] + ;
- Splay(Get_kth(root,tmp-),);
- Splay(Get_kth(root,tmp+),root);
- s[++tot2] = Key_value;
- Key_value = ;
- push_up(ch[root][]);
- push_up(root);
- if(tmp == size[root])tp = Get_kth(root,);
- else tp = Get_kth(root,tmp);
- }
- int MOVE(int x)
- {
- if(x == )
- {
- Splay(tp,);
- int tmp = size[ch[root][]] + ;
- tmp--;
- if(tmp == )tmp = size[root] - ;
- tp = Get_kth(root,tmp);
- }
- else
- {
- Splay(tp,);
- int tmp = size[ch[root][]] + ;
- tmp++;
- if(tmp == size[root])tmp = ;
- tp = Get_kth(root,tmp);
- //cout<<tp<<endl;
- }
- }
- int query()
- {
- Splay(tp,);
- return key[root];
- }
- char op[];
- int x;
- int main()
- {
- //freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- int iCase = ;
- while(scanf("%d%d%d%d",&n,&q,&k1,&k2) == )
- {
- if(n == && q == && k1 == && k2 == )break;
- iCase ++;
- printf("Case #%d:\n",iCase);
- Init();
- tp = Get_kth(root,);
- while(q--)
- {
- scanf("%s",op);
- if(op[] == 'a')
- {
- scanf("%d",&x);
- ADD(x);
- }
- else if(op[] == 'r')
- REVERSE();
- else if(op[] == 'i')
- {
- scanf("%d",&x);
- INSERT(x);
- }
- else if(op[] == 'd')
- DELETE();
- else if(op[] == 'm')
- {
- scanf("%d",&x);
- MOVE(x);
- }
- else printf("%d\n",query());
- }
- }
- return ;
- }
HDU 4453 Looploop (伸展树splay tree)的更多相关文章
- 树-伸展树(Splay Tree)
伸展树概念 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造. (01) 伸展树属于二 ...
- 纸上谈兵: 伸展树 (splay tree)[转]
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每 ...
- K:伸展树(splay tree)
伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(lgN)内完成插入.查找和删除操作.在伸展树上的一般操作都基于伸展操作:假设想要对一个二叉查找树执行一系列的查找操作,为了使 ...
- 高级搜索树-伸展树(Splay Tree)
目录 局部性 双层伸展 查找操作 插入操作 删除操作 性能分析 完整源码 与AVL树一样,伸展树(Splay Tree)也是平衡二叉搜索树的一致,伸展树无需时刻都严格保持整棵树的平衡,也不需要对基本的 ...
- 【BBST 之伸展树 (Splay Tree)】
最近“hiho一下”出了平衡树专题,这周的Splay一直出现RE,应该删除操作指针没处理好,还没找出原因. 不过其他操作运行正常,尝试用它写了一道之前用set做的平衡树的题http://codefor ...
- 伸展树 Splay Tree
Splay Tree 是二叉查找树的一种,它与平衡二叉树.红黑树不同的是,Splay Tree从不强制地保持自身的平衡,每当查找到某个节点n的时候,在返回节点n的同时,Splay Tree会将节点n旋 ...
- 伸展树(Splay tree)的基本操作与应用
伸展树的基本操作与应用 [伸展树的基本操作] 伸展树是二叉查找树的一种改进,与二叉查找树一样,伸展树也具有有序性.即伸展树中的每一个节点 x 都满足:该节点左子树中的每一个元素都小于 x,而其右子树中 ...
- hdu 2871 Memory Control(伸展树splay tree)
hdu 2871 Memory Control 题意:就是对一个区间的四种操作,NEW x,占据最左边的连续的x个单元,Free x 把x单元所占的连续区间清空 , Get x 把第x次占据的区间输出 ...
- 伸展树Splay
新学的,其实吧,就那么回事.... 看了几天,splay处理序列问题,真的非常厉害,翻转,插入,删除,线段树实现不了的功能,splay用起来很方便. POJ 3580 SuperMemo 这题基本就是 ...
随机推荐
- Linux - ssh 连接问题
SSH 连接方式 ssh -p 22 user@192.168.1.209 # 从linux ssh登录另一台linux ssh -p 22 root@192.168.1.209 CMD # 利用ss ...
- [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)
[BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...
- [转]GCC系列: __attribute__((visibility("")))
在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...
- git merge branch to master
git checkout master git pull git merge testbranch git push
- 终极利器!利用appium和mitmproxy登录获取cookies
环境搭建 参考我之前写的https://www.cnblogs.com/c-x-a/p/9163221.html appium 代码start_appium.py # -*- coding: utf- ...
- 经典sql-获取当前文章的上一篇和下一篇
我们在做资讯类的网站的时候,肯定会有这么一个需求,就是在资讯内容页的下方需要给出上一篇和下一篇资讯的链接.上次我一同事兼好友兼室友就遇到了这么一个需求,一开始我们都把问题想复杂了,先取的是符合条件的资 ...
- org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL
[报错] org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XM ...
- google地图的url参数
Google Maps Intents for Android The Google Maps app for Android exposes several intents that you can ...
- Ubuntu 下 vi 输入方向键会变成 ABCD 的解决方法
Ubuntu 下 vi 输入方向键会变成 ABCD,这是 Ubuntu 预装的是 vim tiny 版本,安装 vim full 版本即可解决. 先卸载vim-tiny: $ sudo apt-get ...
- chisequre test
卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,卡方值越大,越不符合:卡方值越小,偏差越小,越趋于符合,若两个值完全相等时,卡方值就 ...