题意:维护一个圈,实现六个功能,给某位置起的一些数增加某值,反转某一段数,添加删除某些数,移动当前所指的位置,

简单的splay,把圈拆成链,对于每种操作,处理一下。

#define inf 0x3f3f3f3f
#define keyTree (ch[ ch[root][1] ][0]) const int maxn = ; struct SplayTree {
int sz[maxn];
int ch[maxn][];
int pre[maxn];
int root , top1 , top2;
int ss[maxn] , que[maxn]; void Rotate(int x,int f) {
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][] == y ] = x;
ch[x][f] = y;
pre[y] = x;
push_up(y);
}
void Splay(int x,int goal) {
push_down(x);
//puts("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
while(pre[x] != goal) {
int y = pre[x], z = pre[y];
push_down(z);
push_down(y);
push_down(x);
if(pre[pre[x]] == goal) {
Rotate(x , ch[pre[x]][] == x);
} else {
int y = pre[x] , z = pre[y];
int f = (ch[z][] == y);
if(ch[y][f] == x) {
Rotate(x , !f) , Rotate(x , f);
} else {
Rotate(y , f) , Rotate(x , f);
}
}
}
push_up(x);
if(goal == ) root = x;
}
void RotateTo(int k,int goal) {//把第k位的数转到goal下边
int x = root;
push_down(x);
while(sz[ ch[x][] ] != k) {
// printf("x = %d k = %d sz[x] = %d\n",x,k,sz[x]);
if(k < sz[ ch[x][] ]) {
x = ch[x][];
} else {
k -= (sz[ ch[x][] ] + );
x = ch[x][];
}
push_down(x);
}
Splay(x,goal);
} //以上一般不修改//////////////////////////////////////////////////////////////////////////////
void debug() {
printf("%d\n",root);
Treaval(root);
}
void Treaval(int x) {
push_down(x);
if(x) {
Treaval(ch[x][]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][],ch[x][],pre[x],sz[x],val[x]);
Treaval(ch[x][]);
}
}
//以上Debug
//以下是题目的特定函数:
void NewNode(int &x,int c) {
x = ++top1;
ch[x][] = ch[x][] = pre[x] = ;
sz[x] = ;
val[x] = c;
lazy[x] = add[x] = ;
}
//把延迟标记推到孩子
void push_down(int x) {
if(lazy[x] != )
{
rev(ch[x][]);
rev(ch[x][]);
//swap(add[ch[x][0]],add[ch[x][1]]);
lazy[x] = ;
}
if(add[x] != )
{
val[ch[x][]] += add[x];
val[ch[x][]] += add[x];
add[ch[x][]] += add[x];
add[ch[x][]] += add[x];
add[x] = ;
}
return ;
}
//把孩子状态更新上来
void push_up(int x) {
sz[x] = + sz[ ch[x][] ] + sz[ ch[x][] ];
}
/*初始化*/
void makeTree(int &x,int l,int r,int f) {
if(l > r) return ;
int m = (l + r)>>;
NewNode(x , num[m]); /*num[m]权值改成题目所需的*/
makeTree(ch[x][] , l , m - , x);
makeTree(ch[x][] , m + , r , x);
pre[x] = f;
push_up(x);
}
void clear() {
cnt = ;
ch[][] = ch[][] = pre[] = sz[] = ;
add[] = lazy[] = ;
root = top1 = ;
//为了方便处理边界,加两个边界顶点
NewNode(root , -inf);
NewNode(ch[root][] , inf);
pre[top1] = root;
sz[root] = ;
}
void init(int pos,int n) {
clear();
cnt = n;
RotateTo(pos , );
RotateTo(pos + , root);
makeTree(keyTree , , n , ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void update(int u,int v,int _add )
{
RotateTo(u - , );
RotateTo(v + , root );
add[keyTree] += _add;
val[keyTree] += _add;
push_up(root);
//Splay(keyTree,root);
}
void rev(int x)
{
if(x == ) return;
swap(ch[x][] ,ch[x][]);
lazy[x] ^= ;
}
void lz(int u,int v )
{
RotateTo(u - , );
RotateTo(v + , root );
rev(keyTree);
//Splay(keyTree,root);
}
int split(int u,int v )
{
RotateTo(u - , );
RotateTo(v + , root );
int res = keyTree;
keyTree = ;
push_up(ch[root][]);
push_up(root);
return res ;
}
void hb(int k,int ts)
{
RotateTo(k - , );
RotateTo(k , root);
keyTree = ts ;
pre[ts] = ch[root][];
push_up(ch[root][]);
push_up(root);
}
void insert(int k,int val)
{
cnt ++ ;
RotateTo(k - , );
RotateTo(k , root ) ;
NewNode(keyTree,val);
pre[keyTree] = ch[root][];
push_up(ch[root][]);
push_up(root);
}
int getkth(int k )
{
int x = root ;
push_down(x);
while(sz[ ch[x][] ] != k) {
// printf("x = %d k = %d sz[x] = %d\n",x,k,sz[x]);
if(k < sz[ ch[x][] ]) {
x = ch[x][];
} else {
k -= (sz[ ch[x][] ] + );
x = ch[x][];
}
push_down(x);
}
return val[x];
}
void del(int k) {
RotateTo(k - , );
RotateTo(k + , root);
//printf("val = %d\n",val[keyTree]);
//printf("sz = %d\n",sz[keyTree]);
cnt -- ;
keyTree = ;
push_up(ch[root][]);
push_up(root);
// erase(keyTree);
}
int cnt ;
/*这是题目特定变量*/
int num[maxn];
int val[maxn];
int add[maxn];
int lazy[maxn]; } spt; int n,m,k1,k2;
int wh;
int main()
{
int cas;
cas = ;
char str[];
while(
scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF && !(n == && m == && k1 == && k2 == ) )
{
for(int i = ; i<= n ; i ++ ) scanf("%d",&spt.num[i]);
spt.init(,n);
wh = ;
printf("Case #%d:\n",++cas);
int x;
while(m -- )
{
scanf("%s",str);
if( str[] == 'q' )
{
int ans = spt.getkth(wh);
printf("%d\n",ans);
}
else if( str[] == 'r' )
{
if(wh + k1 - <= spt.cnt)
{
spt.lz(wh , wh + k1 - );
}
else
{
int p1,p2,p3,p4;
p4 = spt.cnt;
p1 = wh + k1 - - spt.cnt;
p2 = spt.split(,p1);
wh = wh - p1;
p4 = p4 - p1;
spt.hb(p4 + ,p2);
p1 = wh + k1 - ;
spt.lz(wh,p1);
}
}
else if(str[] == 'i')
{
scanf("%d",&x);
spt.insert(wh + ,x);
}
else if(str[] == 'm')
{
scanf("%d",&x);
if(x == )
{
wh -- ;
if(wh == ) wh = spt.cnt;
}
else
{
wh ++ ;
if(wh >spt.cnt) wh = ;
}
}
else if(str[] == 'd')
{
if(wh == spt.cnt)
{
spt.del(wh);
wh = ;
}
else
{
spt.del(wh);
}
}
else if(str[] == 'a')
{
scanf("%d",&x);
int p1,p2,p3,lef;
if(wh + k2 - <= spt.cnt)
{
spt.update(wh,wh + k2 - ,x);
}
else
{
lef = wh + k2 - - spt.cnt;
// printf("%d %d \n",k2,lef);
spt.update(,lef,x);
spt.update(wh,spt.cnt,x);
}
}
// spt.debug();
}
}
return ;
}

7k+的代码,居然调出来了,好开心。

hdu4453 Looploop 2012年杭州现场赛 Splay的更多相关文章

  1. 2013杭州现场赛B题-Rabbit Kingdom

    杭州现场赛的题.BFS+DFS #include <iostream> #include<cstdio> #include<cstring> #define inf ...

  2. CCPC2016杭州现场赛

    A(hdu5933):(贪心) 题意:长度为n的数组: a1, a2,⋯, 每次操作要么可以merge两个相邻的数为一个, 值为两个数的和; 要么可以把一个数分裂成两个, 两个数的和为原数. 用最少的 ...

  3. hdu 4779 Tower Defense 2013杭州现场赛

    /** 题意: 有两种塔,重塔,轻塔.每种塔,能攻击他所在的一行和他所在的一列, 轻塔不 能被攻击,而重塔可以被至多一个塔攻击,也就是说重塔只能被重塔攻击.在一个n*m 的矩阵中,最少放一个塔,可放多 ...

  4. hdu 4465 Candy(2012 ACM-ICPC 成都现场赛)

    简单概率题,可以直接由剩余n个递推到剩余0个.现在考虑剩余x个概率为(1-p)的candy时,概率为C(2 * n - x, x) * pow(p, n + 1)  *pow(1 - p, n - x ...

  5. hdu 4472 Count (2012 ACM-ICPC 成都现场赛)

    递推,考虑到一n可以由i * j + 1组合出来,即第二层有j个含有i个元素的子树...然后就可以了.. #include<algorithm> #include<iostream& ...

  6. hdu4445 CRAZY TANK 2012金华赛区现场赛D题

    简单推下物理公式  对角度枚举 物理公式不会推啊智商捉急啊.... 到现在没想通为什么用下面这个公式就可以包括角度大于90的情况啊... #include<iostream> #inclu ...

  7. hdu 4771 Stealing Harry Potter's Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: ...

  8. 2013 ACMICPC 杭州现场赛 I题

    #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #in ...

  9. 2013 Asia acm Hangzhou Regional Contest 杭州现场赛

     B Stealing Harry Potter's Precious 题目大意:给定一个n*m的地图,某些点可以走,某些点可以走某些点不可以走,给定一个起点,又给出了k个点k<=4,要求从起点 ...

随机推荐

  1. 动画(Animation) 它 (闪烁、左右摇摆、跷跷板等功效)

    一侧到另一侧的影响: (这里显示的是并不那么顺利) 一.续播  (不知道取什么名字好,就是先播放动画A, 接着播放动画B) 有两种方式. 第一种.分别动画两个动画,A和B, 然后先播放动画A,设置A ...

  2. [置顶] 最优间隔分类器、原始/对偶问题、SVM的对偶问题——斯坦福ML公开课笔记7

    转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9774135 本篇笔记针对ML公开课的第七个视频,主要内容包括最优间隔分类器( ...

  3. Java 8 时间日期库的20个使用示例

    java 8是如何处理时间及日期的 有人问我学习一个新库的最佳途径是什么?我的回答是,就是在实际项目中那样去使用它.在一个真实的项目中会有各种各样的需求,这会促使开发人员去探索和研究这个新库.简言之, ...

  4. JQuery Easy Ui (Tree树)详解(转)

    第一讲:JQuery Easy Ui到底是什么呢? 首先咱们知道JQuery是对Java Script的封装,是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等.. JQuery ui是在j ...

  5. WinForm、wpf、silverlight三者关系

    最近在学C#.NET,基本语法学习的差不多了,接下来准备学习图形界面设计部分.但是我目前对于.NET的WinForm.wpf.silverlight这三者的关系弄的不是很清楚,一般书中很少介绍wpf和 ...

  6. js你真的了解offsetWidth吗

    offsetWidth是什么? 答:它可以获取物体宽度的数值 那么就只是这样吗! html部分 <div id="div1"></div> <styl ...

  7. 使用 WPF 实现所见即所得HTML编辑器

    Introduction In this tip, you will learn the use of WPF webbrowser control and the use of the librar ...

  8. Hadoop学习笔记Hadoop伪分布式环境建设

    建立一个伪分布式Hadoop周围环境 1.主办(Windows)顾客(安装在虚拟机Linux)网络连接. a) Host-only 主机和独立客户端联网: 好处:网络隔离: 坏处:虚拟机和其他serv ...

  9. cocos2dx-3.0(13)------SpriteBatchNode与SpriteFrameCache渲染速度

    大家都知道一个游戏里面会有大量的图片,每一个图片渲染是须要时间的,以下分析两个类来加快渲染速度,加快游戏执行速度          一.SpriteBatchNode          1.先说下渲染 ...

  10. How to install PL/SQL developer on linux (转)

    PL/SQL developer 在linux上的安装方法工欲善其事必先利其器,PL/SQL和toad对于ORACLE从业人员来说都是很重要的工具,但这些工具都没有linux的发行版,如果要在linu ...