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 这题基本就是 ...
随机推荐
- shell脚本常用参数
shell 脚本 常用参数 #!/bin/sh # 在脚本第一行脚本头 # sh为当前系统默认shell,可指定为bash等shell sh -x # 执行过程 sh -n # 检查语法 (a=bbk ...
- 2017-2018-2 20165227 实验四《Android程序设计》实验报告
一.实验报告封面 课程: Java程序设计 班级: 1652班 姓名: 朱越 学号: 20165227 指导教师: 娄嘉鹏 实验日期: 2018年5月14日 实验时间: 13:45 - 3:25 实验 ...
- Number of Airplanes in the Sky
Given an interval list which are flying and landing time of the flight. How many airplanes are on th ...
- Update Bits
Given two 32-bit numbers, N and M, and two bit positions, i and j. Write a method to set all bits be ...
- LINUX下 USB转串口 【转】
转自:http://blog.163.com/smilexiao_11015461/blog/static/2122052182012102410399459/ 1.将设备u口插入pc2.输入#lsm ...
- Ubuntu下mysql使用
1. 从网上安装 sudo apt-get install mysql-server.装完已经自动配置好环境变量,可以直接使用mysql的命令. 注:建议将/etc/apt/source.list中的 ...
- mybatis generator 双击创建失败
https://coding.imooc.com/learn/questiondetail/20460.html 用的下面这个方法
- finall和set和构造方法的参数意义
package demo04; /* * 形状 */public abstract class Shape { // 求周长 public abstract double getGrith(); // ...
- KnockoutJs学习笔记(七)
if binding与visible binding类似.不同之处在于,包含visible binding的元素会在DOM中一直保存,并且该元素相应的data-bind属性会一直保持,visible ...
- hdu 2519 求组合数
求组合数 如果求C5 3 就是5*4*3/3*2*1 也就是(5/3)*(4/2)*(3/1) Sample Input5 //T3 2 //C3 25 34 43 68 0 Sample Outpu ...