zoukankan      html  css  js  c++  java
  • 【树状数组】密码机(ZJOI2003)

    Description

      一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码。现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码。密码机中存放了一个数列,初始时为空。密码机的控制命令共有3种:

      ADD
        把放到数列的最后。
      REMOVE
        在数列中找出第一个等于的数,把它从数列中删除。
      XOR BETWEEN AND
        对于数列中所有大于等于并且小于等于的数依次进行异或,输出最后结果作为密码。如果只有一个数满足条件,输出这个数。如果没有任何数满足条件,输出0。

      你可以假设用户不会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
    ",ask(x-1)^ask(y));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    OC中ARC forbids explicit message send of release错误
    OC中内存管理(转)
    [题解]数学期望_luogu_P1850_换教室
    [题解](单调队列)luogu_P2216_BZOJ_1047 理想的正方形
    [题解]luogu_AT1224_JOIOJI
    [题解]区间dp_luogu_P3147 262144
    [筆記]歐拉路
    [題解/狀壓dp]POJ_2411_Mondriaan's dream
    [題解]luogu_P1854 花店櫥窗佈置
    [題解]luogu_P1052 過河
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/13427609.html
Copyright © 2011-2022 走看看