【树状数组】密码机(ZJOI2003)
Description
一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码。现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码。密码机中存放了一个数列,初始时为空。密码机的控制命令共有3种:
ADD
把
REMOVE
在数列中找出第一个等于
XOR BETWEEN
对于数列中所有大于等于
你可以假设用户不会REMOVE一个不存在于数列中的数,并且所有输入的数都不超过20000。
Input
包括了一系列的控制命令。每个控制命令占据单独一行。输入文件中没有多余的空行。文件不超过60000行。
Output
对于每个XOR命令,依次输出一行包括你的密码机所产生的密码。输出文件中不应该包含任何的多余字符
Sample Input
ADD 5
ADD 6
XOR BETWEEN 1 AND 10
REMOVE 5
XOR BETWEEN 6 AND 8
Sample Output
3
6
思路
- 异或具有aa=0,a0=a的性质
代码
#include <iostream>
#include <cstdio>
using namespace std;
char op[20];
int c[33000];
int lowbit(int x){return x&(-x);}
void add(int x,int d){for(int i=x;i<=33000;i+=lowbit(i)) c[i]^=d;}
int ask(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i)) ans^=c[i];
return ans;
}
int main()
{
while(~scanf("%s",&op))
{
if(op[0]=='A'||op[0]=='R')
{
int x; scanf("%d",&x);
add(x,x);
}
else
{
int x,y; scanf("%s%d%s%d",&op,&x,&op,&y);
if(x>y) puts("0");
else printf("%d\n",ask(x-1)^ask(y));
}
}
return 0;
}