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

简单的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. Nginx Rewrite规则记录

    Rewrite 是一种服务器的重写脉冲技术,它可以使得服务器可以支持 URL 重写,是一种最新流行的服务器技术.它还可以实现限制特定IP访问网站的功能.很多情况下,某个 IP 的访问很容易造成 CPU ...

  2. EasyUI基础searchbox&amp;progressbar(搜索框,进度条)

    easyui学习的基本组成部分(八个部分)硕果仅存searchbox和pargressbar.tooltip该,有一点兴奋.本文将偏向searchbox和pargressbar做一个探讨.鉴于双方的内 ...

  3. 【牛刀小试2】password保

    ]password保 主要知识: 1.        while循环 2.        do-while循环 3.        if-else 4.        strcmp()函数 [充电一下 ...

  4. 使用ThinkPHP框架高速发展网站(多图)

    使用ThinkPHP框架高速搭建站点 这一周一直忙于做实验室的站点,基本功能算是完毕了.比較有收获的是大概了解了ThinkPHP框架.写一些东西留作纪念吧.假设对于相同是Web方面新手的你有一丝丝帮助 ...

  5. linux下改动内核參数进行Tcp性能调优 -- 高并发

    前言: Tcp/ip协议对网络编程的重要性,进行过网络开发的人员都知道,我们所编写的网络程序除了硬件,结构等限制,通过改动Tcp/ip内核參数也能得到非常大的性能提升, 以下就列举一些Tcp/ip内核 ...

  6. lua.c:80:31: fatal error: readline/readline.h: No such file or directory

    make linuxcd src && make linuxmake[1]: Entering directory `/root/lua/lua-5.3.2/src'make all ...

  7. SNMP WINDOWS系统的命令行工具下载

    SNMP windows系统的命令行工具snmputil.exe下载链接:请点击

  8. OFTP说明

    OFTP (TheOdette File Transfer Protocol,RFC 2204)作为两个商业伙伴中建立EDI连接的一种协议.它由Odette-Organization于1986年创建. ...

  9. 未能加载文件或程序集“Common”或它的某一个依赖项。试图加载格式不正确的程序

    原因:操作系统是64位的,但发布的程序引用了一些32位的ddl,所以出现了兼容性的问题解决方案一:如果是64位机器,IIS——应用程序池——高级设置——启用32位应用程序 :true.解决方案二:修改 ...

  10. [Java][Android][Process] 分享 Process 运行命令行封装类型

    我在以前的文章中提到,使用Java不会有一个问题,创建运行命令来创建太多进程后创建进程行语句. [Android] ProcessBuilder与Runtime.getRuntime().exec分别 ...