题意:三个操作insert qmin qmax,利用某种数据结构,求y^x最大或最小,其中y为询问的时候给出的,x为insert进去的.
分析:利用字典数将insert进去的数存起来,字典树从根的儿子结点到最后的叶子结点依次存放数据的二进制高位到低位,然后查询.对于x^y最大值的查询,当然要看有没有与y当前位不同的,而最小值就看有没有与当前位相反的...
参考代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int inf = 0x3f3f3f3f;
const int maxn = 1e4;
int n;
//TrieTree
int tt[320000][2];
int node;//结点个数
void init()
{
mem(tt[0],0);
node = 1;
}
void Insert( int num)
{
int rt = 0;
for( int i = 30; i >= 0; i--)//2^31>1e9
{
int id = ((1<<i)&num)>>i;//求出num的第i位是1还是0
if( !tt[rt][id])//结点不存在,新建一个
{
mem(tt[node],0);
tt[rt][id] = node++;
}
rt = tt[rt][id];
}
}
//求最小值
int QueryMin( int num)
{
int rt = 0;
int ans = 0;
for( int i = 30; i >= 0; i--)
{
int id = ((1<<i)&num)>>i;
if( tt[rt][id])//相同的存在
rt = tt[rt][id];
else
{
ans += (1<<i);
rt = tt[rt][1-id];
}
}
return ans;
}
//求最大值
int QueryMax( int num)
{
int rt = 0;
int ans = 0;
for( int i = 30; i >= 0; i--)
{
int id = ((1<<i)&num)>>i;
if( tt[rt][1-id])//相反的存在
{
ans += (1<<i);
rt = tt[rt][1-id];
}
else
rt = tt[rt][id];
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while( T--)
{
init();
scanf("%d",&n);
while( n--)
{
char op[10];
int num;
scanf("%s%d",op,&num);
if( !strcmp(op,"insert"))
Insert(num);
else if( !strcmp(op,"qmin"))
printf("%d\n",QueryMin(num));
else if( !strcmp(op,"qmax"))
printf("%d\n",QueryMax(num));
}
}
return 0;
}