刷题集-密码机

题意:一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码。现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码。
密码机中存放了一个数列,初始时为空。密码机的控制命令共有3种:
ADD <Number>
把<Number>加入到数列的最后。
REMOVE <Number>
在数列中找出第一个等于<Number>的数,把它从数列中删除。
XOR BETWEEN <Number1> AND <Number2>
对于数列中所有大于等于<Number1>并且小于等于<Number2>的数依次进行异或,输出最后结果作为密码。如果只有一个数满足条件,输出这个数。如果没有任何数满足条件,输出0。
你可以假设用户不会REMOVE一个不存在于数列中的数,并且所有输入的数都不超过20000。

没啥好说的,一棵权值线段树就好了。

#include<bits/stdc++.h>
using namespace std;
const int N=20010;
int seg[N<<2];
void push_up(int k)
{seg[k]=seg[k<<1]^seg[k<<1|1];}
int cg(int l,int r,int k,int to)
{
    if(l==r)seg[k]^=to;
    else
    {
        int mid=(l+r)>>1;
        if(to<=mid)cg(l,mid,k<<1,to);
        else cg(mid+1,r,k<<1|1,to);
        push_up(k);
    }
}
int ask(int L,int R,int l,int r,int k)
{
    if(L<=l&&r<=R)return seg[k];
    if(l>R||r<L)return 0;
    int mid=(l+r)>>1;
    return ask(L,R,l,mid,k<<1)^ask(L,R,mid+1,r,k<<1|1);
}
int main()
{
    int n,nw,l,r;char s[20];
    while(~scanf("%s",s))
    {
        if(s[0]=='A'||s[0]=='R')scanf("%d",&nw),cg(1,20000,1,nw);
        else
        {
            scanf("%s",s);
            scanf("%d",&l);
            scanf("%s",s);
            scanf("%d",&r);
            printf("%d\n",ask(l,r,1,20000,1));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/caoyang1123/article/details/82595921