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 这题基本就是 ...
随机推荐
- Javascript摸拟自由落体与上抛运动 说明!
JavaScript 代码 //**************************************** //名称:Javascript摸拟自由落体与上抛运动! //作者:Gloot //邮箱 ...
- 20155212 2016-2017-2 《Java程序设计》第6周学习总结
20155212 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 Chapter10 输入串流为java.io.InputStream,输出串流为java.i ...
- tensorflow随机张量创建
TensorFlow 有几个操作用来创建不同分布的随机张量.注意随机操作是有状态的,并在每次评估时创建新的随机值. 下面是一些相关的函数的介绍: tf.random_normal 从正态分布中输出随机 ...
- Linux下创建软Raid
1- Linux下创建软Raid 步骤1.创建磁盘,并转换为fd #fdisk /dev/sdb //这里使用新的磁盘sdb 然后输入n ,创建分区 使用默认的起始点 输入大小为+100M 然后重 ...
- redis,nodejs,php,pub/sub 实战: 微信语音识别
2015年5月22日 20:20:20 星期五 效果: 这边对微信说话, 浏览器端及时显示语音识别的文字 注意: 在连接socket.io时, 按下浏览器f12, 如果一直有请求不断的刷, 说明so ...
- 原生js实现ajax跨域(兼容IE8,IE9)
html设置meta标签兼容360兼容模式和IE怪异模式 <meta http-equiv="X-UA-Compatible" content="IE=9;IE=8 ...
- CRT软件光标不闪烁
点击 选项->会话选项 然后在取消即可,就有了闪烁的光标,应该是个bug 也可以把后面的浏览器之类的东西缩小一下,也会恢复
- [转]solver优化方法
原文地址:http://www.cnblogs.com/denny402/p/5074212.html 到目前为止,caffe总共提供了六种优化方法: Stochastic Gradient Desc ...
- 2018ACM/ICPC 青岛现场赛 E题 Plants vs. Zombies
题意: 你的房子在0点,1,2,3,...,n(n<=1e5)点每个点都有一颗高度为0的花,浇一次水花会长a[i]. 你有一个机器人刚开始在你家,最多走m步,每一步只能往前走或者往后走,每走到一 ...
- 003_Java笔记3:Eclipse添加jar包
本文以jedis包为例,演示Eclipse如何添加和使用jar包. 1 建立一个名为ImportJarDemo的Java Project.在该工程下建立一个libs的文件夹. 2 将下载的jedi ...