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 这题基本就是 ...
随机推荐
- 【NOI】2017 整数(BZOJ 4942,LOJ2302) 压位+线段树
[题目]#2302. 「NOI2017」整数 [题意]有一个整数x,一开始为0.n次操作,加上a*2^b,或询问2^k位是0或1.\(n \leq 10^6,|a| \leq 10^9,0 \leq ...
- CSSOM
概要 狭义的 DOM API 仅仅包含 DOM 树形结构相关的内容. DOM 中的所有的属性都是用来表现语义的属性,CSSOM 的则都是表现的属性. CSSOM 是 CSS 的对象模型,在 W3C 标 ...
- Java使用WebSocket
网页端的消息推送,一般有以下方式: 轮询方式:客户端定时向服务端发送ajax请求,服务器接收到请求后马上返回消息并关闭连接. 优点:后端程序编写比较容易. 缺点:TCP的建立和关闭操作浪费时间和带宽, ...
- zabbix3.0配置服务器流量告警
zabbix配置流量告警 zabbix虽然已经对服务器的网卡流量进行了监控,但为了防止某台机器流量过高导致网络慢,或者因为中病毒或木马等原因,导致流量很高,可使用zabbix的流量告警功能来对流量进行 ...
- vue项目里的日期格式化
在项目中,我们经常需要把后台传回的日期进行格式化,可以在common里定义一个公共的js export function formatDate (date, fmt) { if (/(y+)/.tes ...
- laravel队列,事件简单使用方法
A.队列的使用 1.队列配置文件存储在 config/queue.php 根据自己的情况进行配置 2..env文件 QUEUE_DRIVER=database(根据个人情况配置,redis等) 3.创 ...
- 输出联系变化的数字seq
主要作用:输出联系变化的数字格式:Seq 分割符号 开始 间隔 结束开始默认是1,间隔默认是1,分隔符默认回车一位是结束,两位首末,三位首间隔末,没有四位,开始可以是负数主要参数:-f 指定格式打印- ...
- High-Speed Tracking with Kernelized Correlation Filters
2015年的一篇论文,可参考:http://blog.csdn.net/carrierlxksuper/article/details/46461245. 另参考:http:// ...
- 大数据统计分析平台之一、Kafka单机搭建
1.zookeeper搭建 Kafka集群依赖zookeeper,需要提前搭建好zookeeper 单机模式(7步)(集群模式进阶请移步:http://blog.51cto.com/nileader/ ...
- 生成和打上patch的方法(转载)
原文链接:http://my.oschina.net/fgq611/blog/180750 在团队开发的过程中,经常需要生成patch,或者打上别人提供的patch,那么一般情况是如何操作的呢. 首先 ...