• Choosing The Commander CodeForces


    As you might remember from the previous round, Vova is currently playing a strategic game known as Rage of Empires.

    Vova managed to build a large army, but forgot about the main person in the army - the commander. So he tries to hire a commander, and he wants to choose the person who will be respected by warriors.

    Each warrior is represented by his personality — an integer number pi. Each commander has two characteristics — his personality pj and leadership lj (both are integer numbers). Warrior i respects commander j only if  ( is the bitwise excluding OR of x and y).

    Initially Vova's army is empty. There are three different types of events that can happen with the army:

    • pi — one warrior with personality pi joins Vova's army;
    • pi — one warrior with personality pi leaves Vova's army;
    • pi li — Vova tries to hire a commander with personality pi and leadership li.

    For each event of the third type Vova wants to know how many warriors (counting only those who joined the army and haven't left yet) respect the commander he tries to hire.

    Input

    The first line contains one integer q (1 ≤ q ≤ 100000) — the number of events.

    Then q lines follow. Each line describes the event:

    • pi (1 ≤ pi ≤ 108) — one warrior with personality pi joins Vova's army;
    • pi (1 ≤ pi ≤ 108) — one warrior with personality pi leaves Vova's army (it is guaranteed that there is at least one such warrior in Vova's army by this moment);
    • pi li (1 ≤ pi, li ≤ 108) — Vova tries to hire a commander with personality pi and leadership li. There is at least one event of this type.

    Output

    For each event of the third type print one integer — the number of warriors who respect the commander Vova tries to hire in the event.

    Example

    Input
    5
    1 3
    1 4
    3 6 3
    2 4
    3 6 3
    Output
    1
    0

    Note

    In the example the army consists of two warriors with personalities 3 and 4 after first two events. Then Vova tries to hire a commander with personality 6 and leadership 3, and only one warrior respects him (, and 2 < 3, but , and 5 ≥ 3). Then warrior with personality 4 leaves, and when Vova tries to hire that commander again, there are no warriors who respect him.

    题意:

    给定Q个操作,操作有以下三种:

    1. 加入一个数值为pi的士兵

    2.删除一个数值为pi的士兵

    3. 如果让一个数值为L和P的将军,询问有多少个士兵尊敬他。

    一个士兵尊重这个将军,当且仅当pi^P<L  , (^为异或运算)

    思路:

    建立01字典树,将加入每一个士兵从高位到低位的二进制插入到字典树中,沿途的节点加1,如果删除就是沿途的节点减一。

    当询问有多少个士兵尊敬将军得时候,

    把将军的P值也从二进制的高位到低位遍历,

    如果P在这一位为0,

    当L也在这一位为0,那么如果有这一位为1的士兵,那么这些士兵一定不尊重他,下一步进入这一位为0的找。

    如果P这一位为1

    当L也在这一位为1,那么如果这一位为1的士兵一定会尊敬他,直接加上数量,然后进入这一位为0的找,

    其他情况也这样推就好了。

    细节见我的代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #define rt return
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    
    struct node
    {
        int num;
        node *Next[2];
        node()
        {
            num=0;
            Next[0]=Next[1]=nullptr;
        }
    };
    
    void Add(node *head , int num)
    {
        node *p=head;
        for(int i=31;i>=0;i--)
        {
            int k=((num>>i)&1);
            if(p->Next[k]== nullptr)
            {
                node *q =new node();
                p->Next[k]= q;
            }
            p = p->Next[k];
            p->num++;
        }
    //    p->num=num;
    }
    void Del(node *head ,int num)
    {
        node *p=head;
        for(int i=31;i>=0;i--)
        {
            int k=((num>>i)&1);
            if(p->Next[k]==NULL)
            {
                node * q=new node();
                p->Next[k] = q;
            }
            p = p->Next[k];
            p->num--;
        }
    
    }
    int Find(node *head, int num)
    {
        node *p = head;
        for(int i=31;i>=0;i--)
        {
            int k=((num>>i)&1);
            if(p->Next[k^1]!=NULL)
            {
                 p = p->Next[k^1];
    
            }else
            {
                p = p->Next[k];
            }
        }
        return p->num;
    }
    void query(node * root,int x,int y)
    {
        node *p = root;
        int res=0;
        for(int i=31;i>=0;--i)
        {
            int tx=(x&(1<<i));
            int tl=(y&(1<<i));
            if(tx)
            {
                if(tl)
                {
                    if(p->Next[1])
                        res+=p->Next[1]->num;
                    p=p->Next[0];
                }else
                {
                    p=p->Next[1];
                }
            }else
            {
                if(tl)
                {
                    if(p->Next[0])
                        res+=p->Next[0]->num;
                    p=p->Next[1];
                }else
                {
    
                    p=p->Next[0];
                }
            }
            if(p==nullptr)
                break;//
        }
        printf("%d
    ",res);
    }
    int n;
    int main()
    {
        gg(n);
        node *head = new node();
        repd(i,1,n)
        {
            int op,x,y;
            gg(op);
            if(op==1)
            {
                gg(x);
                Add(head,x);
            }else if(op==2)
            {
                gg(x);
                Del(head,x);
            }else
            {
                gg(x),gg(y);
                query(head,x,y);
            }
        }
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }

    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    linux各文件夹的作用
    CodeIgniter的URL传过来的中文参数处理错误的修复
    syn_ack攻击
    分治排序
    Linux Shell学习笔记
    sql题型
    jquery ajax
    json 字符串与对象之间的转换
    常用的VIM命令列表 移动光标
    visual c++ 2012 内存泄漏检测方法
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10332323.html
Copyright © 2020-2023  润新知