您的位置:首页 > 其它

ZOJ 3765 Lights

2014-03-04 11:54 453 查看
Splay...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 300010
#define INF 0x7FFFFFFF
using namespace std;

struct SplayTree{
int next[2],pre,key,num,work;
int Gopen,Gclose;
} T[maxn];
int root,size;
int a[200000],b[200000];

inline int GCD(int a,int b){
return b == 0 ? a : GCD(b, a % b);
}

inline void PushUp(int x){
int L=T[x].next[0],R=T[x].next[1];
T[x].num=T[L].num+T[R].num+1;
if(T[x].work==1) T[x].Gopen=T[x].key,T[x].Gclose=-1;
else T[x].Gopen=-1,T[x].Gclose=T[x].key;
if (T[L].Gopen==-1) T[x].Gopen=T[R].Gopen;
else if (T[R].Gopen==-1) T[x].Gopen=T[L].Gopen;
else T[x].Gopen=GCD(T[L].Gopen,T[R].Gopen);
if (T[L].Gclose==-1) T[x].Gclose=T[R].Gclose;
else if (T[R].Gclose==-1) T[x].Gclose=T[L].Gclose;
else T[x].Gclose=GCD(T[L].Gclose,T[R].Gclose);

if(T[x].work==1){
if(T[x].Gopen==-1) T[x].Gopen=T[x].key;
else T[x].Gopen=GCD(T[x].Gopen,T[x].key);
}
else{
if(T[x].Gclose==-1) T[x].Gclose=T[x].key;
else T[x].Gclose=GCD(T[x].Gclose,T[x].key);
}
}
inline void NewNode(int &x,int y,int val,int key){
x=++size;
T[x].next[0]=T[x].next[1]=0;
T[x].work=val;
T[x].key=key;
T[x].pre=y;
if(val==1) T[x].Gopen=key,T[x].Gclose=-1;
else T[x].Gopen=-1,T[x].Gclose=key;
T[x].num=1;
}
inline void Rotate(int x,int kind){
int y=T[x].pre,z=T[y].pre;
T[y].next[!kind]=T[x].next[kind];
T[T[x].next[kind]].pre=y;
T[z].next[T[z].next[1]==y]=x;
T[x].pre=z;T[x].next[kind]=y;
T[y].pre=x;
PushUp(y);
}
inline void Splay(int x,int goal){
while(T[x].pre!=goal){
if(T[T[x].pre].pre==goal)
Rotate(x,T[T[x].pre].next[0]==x);
else{
int y=T[x].pre;
int kind=(T[T[y].pre].next[0]==y);
if(T[y].next[kind]==x)
Rotate(x,!kind),Rotate(x,kind);
else
Rotate(y,kind),Rotate(x,kind);
}
}
PushUp(x);
if(goal==0) root=x;
}
int Select(int k){
int x;
for(x=root;T[T[x].next[0]].num+1!=k;){
if(T[T[x].next[0]].num+1 < k){
k-=T[T[x].next[0]].num+1;
x=T[x].next[1];
}
else
x=T[x].next[0];
}
return x;
}
void Changekey(int x,int y,int key){
x=Select(x-1);y=Select(y+1);
Splay(x,0);Splay(y,x);
T[T[y].next[0]].key=key;
if(T[T[y].next[0]].work) T[T[y].next[0]].Gopen=key,T[T[y].next[0]].Gclose=-1;
else T[T[y].next[0]].Gopen=-1,T[T[y].next[0]].Gclose=key;
PushUp(T[y].next[0]);
PushUp(y);PushUp(x);
}
void Changework(int x,int y){
x=Select(x-1);y=Select(y+1);
Splay(x,0);Splay(y,x);
T[T[y].next[0]].work^=1;
swap(T[T[y].next[0]].Gopen,T[T[y].next[0]].Gclose);
PushUp(y);PushUp(x);
}
int GetGopen(int x,int y){
x=Select(x-1);y=Select(y+1);
Splay(x,0);Splay(y,x);
return T[T[y].next[0]].Gopen;
}
int GetGclose(int x,int y){
x=Select(x-1);y=Select(y+1);
Splay(x,0);Splay(y,x);
return T[T[y].next[0]].Gclose;
}
void Delete(int x,int y){
x=Select(x-1);y=Select(y+1);
Splay(x,0);Splay(y,x);
T[y].next[0]=0;
PushUp(T[root].next[1]);
}
void Build(int &x,int L,int R,int father){
if(L<=R){
int mid=(L+R)>>1;
NewNode(x,father,b[mid],a[mid]);
Build(T[x].next[0],L,mid-1,x);
Build(T[x].next[1],mid+1,R,x);
PushUp(x);
}
}
inline void Insert(int x,int y,int key,int work){
x=Select(x);Splay(x,0);
y=Select(y+1);Splay(y,x);
NewNode(T[y].next[0],y,work,key);
PushUp(T[root].next[1]);
PushUp(root);
}
void Init(int n){
root=size=0;
T[0].next[0]=T[0].next[1]=T[0].num=0;
T[0].key=T[0].Gopen=T[0].Gclose=0;
T[0].work=false;
NewNode(root,0,false,0);
NewNode(T[root].next[1],root,false,0);
Build(T[T[root].next[1]].next[0],1,n,T[root].next[1]);
PushUp(T[root].next[1]);
PushUp(root);
}
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF){
int key,work;
for(int i=1;i<=n;++i)
scanf("%d%d",&a[i],&b[i]);
Init(n);
char cmd[10];
int L,R,ans;
while(q--){
scanf("%s",cmd);
if(cmd[0]=='Q'){
scanf("%d%d%d",&L,&R,&work);
if(work==0) ans=GetGclose(L+1,R+1);
else ans=GetGopen(L+1,R+1);
if(!ans) ans=-1;
printf("%d\n",ans);
}
else if(cmd[0]=='I'){
scanf("%d%d%d",&L,&key,&work);
Insert(L+1,L+1,key,work);
}
else if(cmd[0]=='D'){
scanf("%d",&L);
Delete(L+1,L+1);
}
else if(cmd[0]=='M'){
scanf("%d%d",&L,&key);
Changekey(L+1,L+1,key);
}
else if(cmd[0]=='R'){
scanf("%d",&L);
Changework(L+1,L+1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: