您的位置:首页 > 运维架构

hdu 4453 Looploop(splay)

2015-01-14 16:00 351 查看
hdu4454Looploop

一看到有旋转操作就splay了

做两个lazy标记: flip(旋转), add(增加)

六种操作

增加,删除,旋转,插入,移动,查询

1.add增加:add(x) 对前k2个数字增加x

将从箭头指向位置开始前k2个节点从树中分离,分离出来的根节点add+x,再将两棵树合并

2.reverse旋转: 将前k1个数字颠倒过来

将从箭头指向位置开始前k1个节点从书中分离,分离出来的根节点flip=1, 再将两棵树合并

3.insert插入: insert(x) 在箭头指向位置的后面插入一个x

将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,在根与根的右孩子前插入x即可,节点数n+1

4.delete删除:将箭头指向位置的数字删除,箭头顺时针移动一个位置(右移/后移)

将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,将树根删除,将原树根右孩子设为新根,节点数n-1

5.move移动:move(x), x=1箭头逆时针移动(左移/前移),x=2箭头顺时针移动(右移/后移)

x=1 将n位置的节点从树中分离,将原根设为其右孩子:root=splay(n),root->child[1]=splay(1);

x=2与此类似

6.query查询:输出箭头指向位置的数字

将指向位置伸展为树根,root=splay(1),output:root->value

===========================================================

刚开始new节点,果断超时,后来开了数组,newnode(int) 替换new node(int)

node lk[maxn];
int cnt;
node* newnode(int v)
{
lk[cnt]=node(v);
return lk+cnt++;
}


build(root, 1, N);
cnt=0;
一直是运行出错调试了一上午 = = 。。。。。。。飙泪

最后发现cnt出了问题,竟然sb的build之后cnt=0.。。

代码如下: 343ms

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 2e5+5;
int N, M, K1, K2;

int hdu[maxn];
struct node
{
node *child[2];
int size;
int value;
int flip;
int add;
node ();
node(int);
void pushup();
void pushdown();
int rank();
int cmp(int k);
}null, *root, lk[maxn];
int cnt;
node* newnode(int v)
{lk[cnt]=node(v);
return lk+cnt++;
}
int node:: cmp(int k)
{
if(k==rank()) return -1;
return k < rank() ? 0 : 1;
}
int node:: rank()
{
return child[0]->size+1;
}
void node:: pushdown()
{
if(flip)
{
swap(child[0], child[1]);
child[0]->flip^=1;
child[1]->flip^=1;
flip=0;
}
if(add)
{
value+=add;
child[0]->add+=add;
child[1]->add+=add;
add=0;
}
}
void node:: pushup()
{
size=child[0]->size+child[1]->size+1;
}
node:: node()
{
child[0]=child[1]=&null;
size=0;
flip=0;
add=0;
}
node:: node(int _value): value(_value)
{
child[0]=child[1]=&null;
size=1;
flip=0;
add=0;
}
void rotate(node*&o, int d)
{
o->pushdown();
node *t=o->child[d];
t->pushdown();
o->child[d]=t->child[d^1];
t->child[d^1]=o;
o->pushup();
o=t;
o->pushup();
}
void splay(node*& o, int k)
{
o->pushdown();
int d=o->cmp(k);
if(~d)
{
if(d) splay(o->child[d], k-o->rank());
else splay(o->child[d], k);
rotate(o, d);
}
}
void build(node*&o, int l ,int r)
{
int m= (l+r)>>1;
o=newnode(hdu[m]);

if(m>l) build(o->child[0], l, m-1);
if(m<r) build(o->child[1], m+1, r);

o->pushup();
}

void add(int x)
{
splay(root, K2);
root->value+=x;
root->child[0]->add+=x;
}
void reverse()
{
splay(root, K1);

node*temp=root->child[1];
root->child[1]=&null;
root->pushup();

root->flip=1;
root->pushdown();
splay(root, K1);

root->child[1]=temp;
root->pushup();
}
void insert(int x)
{
splay(root, 1);

node *temp=newnode(x);
temp->child[1]=root->child[1];
temp->pushup();

root->child[1]=temp;
root->pushup();

N++;
}
void remove()
{
splay(root, 1);
node *temp=root->child[1];
root=temp;
root->pushdown();

N--;
}
void move(int x)
{
if(x==1)
{
splay(root, N);
node *temp = root->child[0];
root->child[0]=&null;

temp->pushdown();
splay(temp, 1);
root->child[1]=temp;
root->pushup();
}
else
{
splay(root, 1);
node *temp = root->child[1];
root->child[1]=&null;

temp->pushdown();
splay(temp, N-1);
root->child[0]=temp;
root->pushup();
}
}

int main()
{
int kase=1;
while(cin>>N>>M>>K1>>K2 && N|M|K1|K2)
{
for(int i=1;i<=N;i++) scanf("%d", hdu+i); cnt=0;
build(root, 1, N);
printf("Case #%d:\n", kase++);
while(M--)
{
char op1[10]; scanf("%s", op1);
if(!strcmp(op1, "add"))
{
int op2; scanf("%d", &op2);
add(op2);
}
else if(!strcmp(op1, "reverse"))
{
reverse();
}
else if(!strcmp(op1, "insert"))
{
int op2; scanf("%d", &op2);
insert(op2);
}
else if(!strcmp(op1, "delete"))
{
remove();
}
else if(!strcmp(op1, "move"))
{
int op2; scanf("%d", &op2);
move(op2);
}
else
{
splay(root, 1);
printf("%d\n", root->value);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: