hdu4453 Looploop 2012年杭州现场赛 Splay
题意:维护一个圈,实现六个功能,给某位置起的一些数增加某值,反转某一段数,添加删除某些数,移动当前所指的位置,
简单的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的更多相关文章
- 2013杭州现场赛B题-Rabbit Kingdom
杭州现场赛的题.BFS+DFS #include <iostream> #include<cstdio> #include<cstring> #define inf ...
- CCPC2016杭州现场赛
A(hdu5933):(贪心) 题意:长度为n的数组: a1, a2,⋯, 每次操作要么可以merge两个相邻的数为一个, 值为两个数的和; 要么可以把一个数分裂成两个, 两个数的和为原数. 用最少的 ...
- hdu 4779 Tower Defense 2013杭州现场赛
/** 题意: 有两种塔,重塔,轻塔.每种塔,能攻击他所在的一行和他所在的一列, 轻塔不 能被攻击,而重塔可以被至多一个塔攻击,也就是说重塔只能被重塔攻击.在一个n*m 的矩阵中,最少放一个塔,可放多 ...
- 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 ...
- hdu 4472 Count (2012 ACM-ICPC 成都现场赛)
递推,考虑到一n可以由i * j + 1组合出来,即第二层有j个含有i个元素的子树...然后就可以了.. #include<algorithm> #include<iostream& ...
- hdu4445 CRAZY TANK 2012金华赛区现场赛D题
简单推下物理公式 对角度枚举 物理公式不会推啊智商捉急啊.... 到现在没想通为什么用下面这个公式就可以包括角度大于90的情况啊... #include<iostream> #inclu ...
- hdu 4771 Stealing Harry Potter's Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@' 表示的是起点,'#' 表示的是障碍物不能通过,'.' 表示的是路能通过的: ...
- 2013 ACMICPC 杭州现场赛 I题
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #in ...
- 2013 Asia acm Hangzhou Regional Contest 杭州现场赛
B Stealing Harry Potter's Precious 题目大意:给定一个n*m的地图,某些点可以走,某些点可以走某些点不可以走,给定一个起点,又给出了k个点k<=4,要求从起点 ...
随机推荐
- 动画(Animation) 它 (闪烁、左右摇摆、跷跷板等功效)
一侧到另一侧的影响: (这里显示的是并不那么顺利) 一.续播 (不知道取什么名字好,就是先播放动画A, 接着播放动画B) 有两种方式. 第一种.分别动画两个动画,A和B, 然后先播放动画A,设置A ...
- [置顶] 最优间隔分类器、原始/对偶问题、SVM的对偶问题——斯坦福ML公开课笔记7
转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9774135 本篇笔记针对ML公开课的第七个视频,主要内容包括最优间隔分类器( ...
- Java 8 时间日期库的20个使用示例
java 8是如何处理时间及日期的 有人问我学习一个新库的最佳途径是什么?我的回答是,就是在实际项目中那样去使用它.在一个真实的项目中会有各种各样的需求,这会促使开发人员去探索和研究这个新库.简言之, ...
- JQuery Easy Ui (Tree树)详解(转)
第一讲:JQuery Easy Ui到底是什么呢? 首先咱们知道JQuery是对Java Script的封装,是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等.. JQuery ui是在j ...
- WinForm、wpf、silverlight三者关系
最近在学C#.NET,基本语法学习的差不多了,接下来准备学习图形界面设计部分.但是我目前对于.NET的WinForm.wpf.silverlight这三者的关系弄的不是很清楚,一般书中很少介绍wpf和 ...
- js你真的了解offsetWidth吗
offsetWidth是什么? 答:它可以获取物体宽度的数值 那么就只是这样吗! html部分 <div id="div1"></div> <styl ...
- 使用 WPF 实现所见即所得HTML编辑器
Introduction In this tip, you will learn the use of WPF webbrowser control and the use of the librar ...
- Hadoop学习笔记Hadoop伪分布式环境建设
建立一个伪分布式Hadoop周围环境 1.主办(Windows)顾客(安装在虚拟机Linux)网络连接. a) Host-only 主机和独立客户端联网: 好处:网络隔离: 坏处:虚拟机和其他serv ...
- cocos2dx-3.0(13)------SpriteBatchNode与SpriteFrameCache渲染速度
大家都知道一个游戏里面会有大量的图片,每一个图片渲染是须要时间的,以下分析两个类来加快渲染速度,加快游戏执行速度 一.SpriteBatchNode 1.先说下渲染 ...
- How to install PL/SQL developer on linux (转)
PL/SQL developer 在linux上的安装方法工欲善其事必先利其器,PL/SQL和toad对于ORACLE从业人员来说都是很重要的工具,但这些工具都没有linux的发行版,如果要在linu ...