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,要求从起点 ...
随机推荐
- 原创游戏,金庸群侠传X 0.5公布
首先说一下背景,我个人从小特别爱玩游戏,对小时候一款游戏<金庸群侠传>DOS版更是情有独钟,自己工作以后,利用业余时间自己整了一个原创的改编版丢网上(找图片.音乐.写剧情更是虐心之极,耗时 ...
- 怎样在Android开发中FPS游戏实现的两种方式比较
怎样在Android开发中FPS游戏实现的两种方式比较 如何用Android平台开发FPS游戏,其实现过程有哪些方法,这些方法又有哪些不同的地方呢?首先让我们先了解下什么是FPS 英文名:FPS (F ...
- LeetCode204:Count Primes
Description: Count the number of prime numbers less than a non-negative number, n. 比计算少n中素数的个数. 素数又称 ...
- Python re正则表达式
参考: 博客园<Python正則表達式指南> 博客园<Python之re模块> 在此感谢博主的无私奉献,本文主要介绍python中re模块的几个简单使用方法.具体的使用方法请參 ...
- 希尔排序java
希尔排序简述 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率.(希尔排序先将部分数据进行排序,相当于已经部分排好序) ...
- Visual Studio 2010 将网站直接发布到远程站点
原文:Visual Studio 2010 将网站直接发布到远程站点 这次说下如何将web应用程序直接发布到IIS服务器站点!!! 问题的由来 本人每天要发布更新的程序,所以每次更新的时候要做的工作: ...
- 聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析
1. 引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把 ...
- Lua 服务器Socket通信实例(转)
local socket = require"socket" local host = "127.0.0.1"local port = "843&qu ...
- 【转】d3d的投影矩阵推导
原帖地址:http://blog.csdn.net/popy007/article/details/4091967 上一篇文章中我们讨论了透视投影变换的原理,分析了OpenGL所使用的透视投影矩阵的生 ...
- Cntlm安装和配置体验
对于那些谁使用NTLM验证网络代理环境(即除了需要设置的代理主机和端口还需要提供一个域用户名和密码)供.通过代理上网头疼.这主要是由于非常大的软件不支持NTLM的代理(比方眼下的GIT就不能支持NTL ...