[zjoi2003]密码机

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

这题有点智商题的感觉;

xor运算符满足一个性质,就是一个数连续xor一个数两次,这个数不变;

可以利用树状数组,每次add或remove直接xor就行,find的时候找到right的xor结果,left的xor结果,两个再xor,这样重复的就会直接消掉;

实现很简单,想通就行了;

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cstdlib>
 6 #include<ctime>
 7 #include<vector>
 8 #include<algorithm>
 9 #include<queue>
10 using namespace std;
11 #define LL long long
12 const int n=20200;
13 int c[n];
14 int lowbit(int x){return x&-x;}
15 void add(int x,int y){while(x<=n){c[x]^=y;x+=lowbit(x);}}
16 int find(int x){int ans=0;while(x>0){ans^=c[x];x-=lowbit(x);}return ans;}
17 int read(){
18     int x=0;bool flag=0;char ch=getchar();
19     while(ch<'0'||ch>'9'){ch=getchar();if(ch=='-')flag=1;}
20     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
21     return flag?-x:x;
22 }
23 void init(){
24     char s[30];
25     while(scanf("%s",s)!=EOF){
26         if(s[0]=='A'||s[0]=='R'){
27             int x=read();
28             add(x,x);
29         }
30         if(s[0]=='X'){
31             int x=read(),y=read();
32             if(x>y){
33                 printf("0
");
34                 continue;
35             }
36             int p=find(x-1),q=find(y);
37             cout<<(p^q)<<endl;
38         }
39     }
40 }
41 int main(){
42     init();
43 }
View Code
原文地址:https://www.cnblogs.com/chadinblog/p/5868090.html