1. 程式人生 > >Choosing The Commander CodeForces - 817E (01字典樹+思維)

Choosing The Commander CodeForces - 817E (01字典樹+思維)

integer 異或運算 got from != rac pri 尊重 org

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:

  • 1 pi — one warrior with personality pi joins Vova‘s army;
  • 2 pi — one warrior with personality pi leaves Vova‘s army;
  • 3 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:

  • 1 pi (1 ≤ pi ≤ 108) — one warrior with personality pi joins Vova‘s army;
  • 2 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);
  • 3 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), ‘\0‘, 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\n",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 == \n);
    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;
        }
    }
}

Choosing The Commander CodeForces - 817E (01字典樹+思維)