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 这题基本就是 ...
随机推荐
- AC自动机(病毒侵袭 )
题目链接:https://cn.vjudge.net/contest/280743#problem/B 题目大意:中文题目 具体思路:AC自动机模板题,编号的时候注意,是按照给定的id进行编号的.然后 ...
- [转]CMake cache
CMakeCache.txt 可以将其想象成一个配置文件(在Unix环境下,我们可以认为它等价于传递给configure的参数). CMakeLists.txt 中通过 set(... CACHE . ...
- mysql Keepalived 实践
Keepalived 是一种高性能的服务器高可用或热备解决方案,Keepalived可以用来防止服务器单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生,通过配合Nginx可 ...
- node.js 安装 测试
2014年5月1日 18:48:01 安装: 系统是centos,里边的python版本是2.4,但是node.js 源码tar包安装要求是 2.6 或者 2.7 下载python 2.7编译安装,注 ...
- js 替换任意字符串中间几位为*星号
<script> var str='河南纳智企业管理咨询有限公司'; a=str.substr(0,2)+'***'+str.substr(5,str.split('').length); ...
- Spring加载XML配置文件
原创链接:http://www.cnblogs.com/yanqin/p/5282929.html(允许转载,但请注明原创链接) BeanFactory加载单个文件 当使用beanfactory去获取 ...
- PHP中的__clone()
1 <?php 2 class Account { 3 public $balance; 4 5 public function __construct($balance) { 6 $this- ...
- javascript-序列化,时间,eval,转义
一:序列化 JSON.stringify(li) 将对象转字符串 JSON.parse(str1) 将字符串转对象 li=[11,22,33] [11, 22, 33] li [11, 22, 33] ...
- Oracle优化技巧
现观察线上系统运行发现,线上某些业务查询存在等待时间长问题,后核查发现,部分问题出现在对数据库操作上Cost大部分时间,后根据网上各位前辈提供的优化技巧解决大部分问题,现写下本篇文章,一来巩固加深自己 ...
- Mockito 简明教程
什么是 Mock 测试 Mock 测试就是在测试过程中,对于某些不容易构造(如 HttpServletRequest 必须在Servlet 容器中才能构造出来)或者不容易获取比较复杂的对象(如 JDB ...