其他分享
首页 > 其他分享> > CF817E Choosing The Commander 题解

CF817E Choosing The Commander 题解

作者:互联网

有Q次操作,每次操作有三种类型,分别是

1 pi 把 pi 加入集合 S
2 pi 把 pi 从集合 S 中删除
3 pi li 表示查询集合中有多少个元素异或上 pi 后 小于 li

0/1trie树.显然对于每一位,若这一位异或后比li的这一位小,那么该结点所在的子树异或后都必然小于li,而若与li的这一位相等,则向这边迭代.

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 3000005;
int n, tot = 1;
int val[N], tree[N][2];
void add(int k, int v)
{
    int now = 1;
    for (int i = (1 << 30); i; i >>= 1)
    {
        val[now] += v;
        bool temp = k & i;
        if (!tree[now][temp])
            tree[now][temp] = ++tot;
        now = tree[now][temp];
    }
    val[now] += v;
}
int query(int v, int l)
{
    int now = 1, ans = 0;
    for (int i = (1 << 30); i; i >>= 1)
    {
        bool temp1 = v & i, temp2 = l & i;
        if (temp1 < temp2)
            ans += val[tree[now][0]];
        if (temp1 && temp2)
            ans += val[tree[now][1]];
        if (temp2)
            now = tree[now][temp1 ^ 1];
        else
            now = tree[now][temp1];
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        if (x == 1)
        {
            int v;
            cin >> v;
            add(v, 1);
        }
        if (x == 2)
        {
            int v;
            cin >> v;
            add(v, -1);
        }
        if (x == 3)
        {
            int v, l;
            cin >> v >> l;
            cout << query(v, l) << endl;
        }
    }
}

标签:pi,val,int,题解,tree,li,CF817E,Choosing,now
来源: https://www.cnblogs.com/KinuhataSaiai/p/15550664.html