您的位置:首页 > 其它

Codeforces 706D Trie树/multiset

2016-09-01 09:20 363 查看
题目:http://codeforces.com/problemset/problem/706/D

题意:

+表示吧这个数加到集合中,-表示把这个数从集合中减去一次,?表示集合里面的一个y使的x^y最大

分析:

要使异或最大,那么尽量从高位使两个数不同即可。

Trie树。

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+9;
int a
[2],cal
;
int tot;
void add(int x,int y) //插入或删除一个元素
{
int cur=0;
for(int i=31;i>=0;i--){
int t=(x>>i)&1;
if(!a[cur][t])a[cur][t]=tot++;
cur=a[cur][t];
cal[cur]+=y;
}
}

int query(int x)
{
int cur=0,ans=0;
for(int i=31;i>=0;i--){
int t=(x>>i)&1;
if(cal[a[cur][t^1]]){
ans+=(1<<i);
cur=a[cur][t^1];
}
else cur=a[cur][t];
}
return ans;
}
int main()
{
int n,x;
char op;
tot=1;
add(0,1);
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>op>>x;
if(op=='+'){
add(x,1);
}
else if(op=='-'){
add(x,-1);
}
else{
printf("%d\n",query(x));
}
}
return 0;
}
/*
Input
10
+ 8
+ 9
+ 11
+ 6
+ 1
? 3
- 8
? 3
? 8
? 11

Output
11
10
14
13
*/


或者可以直接用multiset模拟:

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+9;

int main()
{
int n,x;
char op;
multiset<int>s;
s.insert(0);
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>op>>x;
if(op=='+'){
s.insert(x);
}
else if(op=='-'){
s.erase(s.find(x));
}
else{
int ans=0;
for(int i=31;i>=0;i--){
ans|=(~x&(1<<i));
multiset<int>::iterator it=s.lower_bound(ans);
if(it==s.end()||*it>=ans+(1<<i)){
// cout<<ans<<endl;
ans^=1<<i;
}
}
printf("%d\n",x^ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: