ZOJ 3765 Lights

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值