[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\n"); 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 }