您的位置:首页 > 其它

codeforces 706D trie树 或 muliset

2016-08-13 17:09 387 查看
题意:插入,删除,询问三个操作。

分析:显然trie树都支持这三个操作,但是代码比较长,用muliset更短小精悍。但是两者的本质都是一样,都是找与二进制不同的,尽量凑成全是1.

muliset

#include<bits/stdc++.h>
using namespace std;
multiset<int> dp;
bool check(int a,int b)
{
auto it = dp.lower_bound(a);
if(it == dp.end()) return false;
if(*it < b) return true;
else return false;
}
int solve(int x)
{
int ans = 0;
for(int i = 30; i >= 0 ; i --)
{
if(!((x>>i)&1)) ans |= 1<<i;
if(!check(ans , ans + (1<<i))) ans ^= 1<<i;
}
return ans^x;
}
int main(void)
{
int q,a;
char c;
cin>>q;
dp.insert(0);
while(q--)
{
cin>>c>>a;
if(c=='+')
dp.insert(a);
else if(c == '-')
{
auto it = dp.find(a);
dp.erase(it);
}
else cout<<solve(a)<<endl;
}
} trie树
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 20;
struct Trie
{
int ch[maxn<<5][2],val[maxn<<5],sz = 0;
void inin(){
sz = 1;memset(ch[0],0,sizeof(ch[0]));
}
void insert(int x,int v)
{
int u = 0;
for(int i = 30 ; i >=0 ; i--)
{
int c = (x>>i) &1;
if(!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
val[u] += v;
}
}
int query(int x)
{
int ans = 0,u = 0;
for(int i = 30 ; i >= 0; i --)
{
int id = (x >> i) & 1;
if(!ch[u][id^1] || !val[ch[u][id^1]])
u = ch[u][id];
else
{
u = ch[u][id^1];
ans |= 1<<i;
}
}
return ans;
}
}tree;
int main(void)
{
tree.inin();
int q,a;
char c;
cin>>q;
tree.insert(0,1);
while(q--)
{
cin>>c>>a;
if(c=='+')
tree.insert(a,1);
else if(c == '-')
{
tree.insert(a,-1);
}
else cout<<tree.query(a)<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: