您的位置:首页 > 其它

伸展树zoj3765

2014-12-02 14:22 295 查看
Lights

Time Limit: 8 Seconds
Memory Limit: 131072 KB

Now you have N lights in a line. Don't worry - the lights don't have color. The only status they have is on and off. And, each light has a value, too.

There is a boring student in ZJU. He decides to do some boring operations to the lights:

Q L R status - Query the GCD (Greatest Common Divisor) ofthe value of the given status lights in range [L,
R]. For example, if now we have 3 lights which are {on, off and on}, and their value are {3, 5, 9}, then the GCD of the number of the lights on in [1, 3] is 3, and the lights off is 5.

I i value status - Add a light just behind toith light. The initial status and the value is givenalso.
D i - Remove the ith light.
R i - If ith light is on, turn it off, else turn it on.

M i x - Modify the value of ith light to
x.

Please help this boring guy to do this boring thing so that he can have time to find a girlfriend!

Input

The input contains multiple test cases. Notice there's no empty line between each test case.

For each test case,the first line of the a case contains two integers, N (1≤
N ≤ 200000) and Q (1 ≤ Q ≤100000), indicating the number of the lights at first and the number ofthe operations.In following
N lines, each line contains two integers, Numi (1 ≤
Numi ≤ 1000000000) and Statusi (0 ≤
Statusi ≤ 1), indicating the number of the light i and the status of it.In following
Q lines, each line indicating an operation, and the format is described above.

It is guaranteed that the range of the operations will be appropriate. For example, if there is only 10 lights, you will not receive an operation like "Q 1 11 0" or "D 11".

Output

For each Query operation, output an integer, which is the answer to the query. If no lights are with such status, please output -1.

Sample Input

3 12
27 1
32 0
9 1
Q 1 3 1
I 3 64 0
Q 2 4 0
Q 2 4 1
I 2 43 1
D 5
Q 1 2 1
M 1 35
Q 1 2 1
R 1
R 3
Q 1 2 1

Sample Output

9
32
9
27
35
-1



都是伸展树的基本操作,进行修改的时候都是



Splay(get_kth(root,x),0);

Splay(get_kth(root,x+2),root);


然后修改ch[ch[root][1]][0]的状态就可以了

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#define Key_value ch[ch[root][1]][0]
using namespace std;
const int  maxn=300010;
int ch[maxn][2],pre[maxn],gcd0[maxn],gcd1[maxn],key[maxn],size[maxn],status[maxn];
int root,tot1,tot2,s[maxn];
int N,Q;
int a[maxn],St[maxn];
void NewNode(int &r,int f,int val,int S)
{
    if(tot2)r=s[tot2--];
    else r=++tot1;
    ch[r][0]=ch[r][1]=0;
    key[r]=val;status[r]=S;
    pre[r]=f;
    size[r]=1;
    gcd0[r]=gcd1[r]=0;
    if(S)gcd1[r]=val;
    else gcd0[r]=val;
}
int GCD(int x,int y)
{
    if(y==0)return x;
    return GCD(y,x%y);
}
void pushup(int r)
{
    int lson=ch[r][0],rson=ch[r][1];
    size[r]=size[lson]+size[rson]+1;
    gcd0[r]=GCD(gcd0[lson],gcd0[rson]);
    gcd1[r]=GCD(gcd1[lson],gcd1[rson]);
    if(status[r])gcd1[r]=GCD(gcd1[r],key[r]);
    else gcd0[r]=GCD(gcd0[r],key[r]);
}
void build(int &x,int l,int r,int f)
{
    if(l>r)return ;
    int mid=(l+r)>>1;
    NewNode(x,f,a[mid],St[mid]);
    build(ch[x][0],l,mid-1,x);
    build(ch[x][1],mid+1,r,x);
    pushup(x);
}
void init()
{
    root=tot1=tot2=0;
    ch[root][0]=ch[root][1]=key[root]=size[root]=0;
    gcd0[root]=gcd1[root]=status[root]=0;
    NewNode(root,0,0,0);
    NewNode(ch[root][1],root,0,0);
    build(Key_value,1,N,ch[root][1]);
    pushup(ch[root][1]);
    pushup(root);
}
void Rotate(int x,int kind)
{
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];
    ch[x][kind]=y;
    pre[y]=x;
    pushup(y);
}
void Splay(int r,int goal)
{
    while(pre[r]!=goal)
    {
        if(pre[pre[r]]==goal)
        {
            Rotate(r,ch[pre[r]][0]==r);
        }
        else
        {
            int y=pre[r];
            int kind=(ch[pre[y]][0]==y);
            if(ch[y][kind]==r)
            {
                Rotate(r,!kind);
                Rotate(r,kind);
            }
            else
            {
                Rotate(y,kind);
                Rotate(r,kind);
            }
        }
    }
    pushup(r);
    if(goal==0)root=r;
}
int get_kth(int r,int k)
{
    int t=size[ch[r][0]]+1;
    if(t==k)return r;
    if(t>k)return get_kth(ch[r][0],k);
    else return get_kth(ch[r][1],k-t);
}
void Query(int l,int r,int y)
{
    Splay(get_kth(root,l),0);
    Splay(get_kth(root,r+2),root);
    int ans=0;
    if(y)ans=gcd1[Key_value];
    else ans=gcd0[Key_value];
    if(!ans)ans=-1;
    printf("%d\n",ans);
}
void Insert(int x,int val,int y)
{
    Splay(get_kth(root,x+1),0);
    Splay(get_kth(root,x+2),root);
    NewNode(Key_value,ch[root][1],val,y);
}
void erase(int r)
{
    if(r)
    {
        s[++tot2]=r;
        erase(ch[r][0]);
        erase(ch[r][1]);
    }
}
void Delete(int x)
{
    Splay(get_kth(root,x),0);
    Splay(get_kth(root,x+2),root);
    erase(Key_value);
    pre[Key_value]=0;
    Key_value=0;
    pushup(ch[root][1]);
    pushup(root);
}
void Reverse(int x)
{
    Splay(get_kth(root,x),0);
    Splay(get_kth(root,x+2),root);
    status[Key_value]^=1;
    pushup(Key_value);
    pushup(ch[root][1]);
    pushup(root);
}
void Modify(int x,int val)
{
    Splay(get_kth(root,x),0);
    Splay(get_kth(root,x+2),root);
    key[Key_value]=val;
    pushup(Key_value);
    pushup(ch[root][1]);
    pushup(root);
}
int main()
{
    char op[10];
    int x,val,l,r,y;
    while(scanf("%d%d",&N,&Q)!=EOF)
    {
        for(int i=1;i<=N;i++)scanf("%d%d",&a[i],&St[i]);
        init();
        while(Q--)
        {
            scanf("%s",op);
            if(op[0]=='Q')
            {
                scanf("%d%d%d",&l,&r,&y);
                Query(l,r,y);
            }
            else if(op[0]=='I')
            {
                scanf("%d%d%d",&x,&val,&y);
                Insert(x,val,y);
            }
            else if(op[0]=='D')
            {
                scanf("%d",&x);
                Delete(x);
            }
            else if(op[0]=='R')
            {
                scanf("%d",&x);
                Reverse(x);
            }
            else
            {
                scanf("%d%d",&x,&val);
                Modify(x,val);
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: