Chip Factory(HDU 5536)和Xor sum(HDU 4825)一样都是01字典树,不过多了一个删除操作,HDU4825只有插入操作,而HDU 5536有删除操作
这里讲解一下删除操作:
定义一个judge[]数组判断每一个节点是否存在即可
在插入的时候令judeg[root]+=1
删除的时候令judge[root]-=1即可
当judge[root]<=0时以该root为前缀的这个数不存在
代码:
void insert_delete(ll x,ll add)//插入和删除操作
{
ll root=0;
for(ll i=31; i>=0; i--)
{
ll id=x>>i&1;
if(!tire[root][id])
tire[root][id]=++tot;
root=tire[root][id];
judge[root]+=add;
}
re_sum[root]=x;
}
题解:
暴力枚举 a[i]+a[j],然后把a[i]和a[j]从tire树上删除,后再添加即可c++会wa,G++可以过,原因我也不知道
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
const ll maxn=10005;
ll tire[31*maxn][2];
ll re_sum[31*maxn];
ll judge[maxn];//判断节点是否被删除
ll tot;//代表总结点数
void insert_delete(ll x,ll add)//插入和删除操作
{
ll root=0;
for(ll i=31; i>=0; i--)
{
ll id=x>>i&1;
if(!tire[root][id])
tire[root][id]=++tot;
root=tire[root][id];
judge[root]+=add;
}
re_sum[root]=x;
}
ll find_num(ll x)
{
ll root=0;
for(ll i=31; i>=0; i--)
{
ll id=x>>i&1;
if(judge[tire[root][id^1]]>0)//贪心思路
root=tire[root][id^1];
else
root=tire[root][id];
}
return re_sum[root];
}
ll a[maxn];
int main()
{
ll t;
//printf("%d\n",1000<<5);
scanf("%lld",&t);
while(t--)
{
memset(tire,0,sizeof(tire));
memset(re_sum,0,sizeof(re_sum));
memset(judge,0,sizeof(judge));
ll n;
scanf("%lld",&n);
tot=0;
for(ll i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
insert_delete(a[i],1);
}
ll maxx=0;
for(ll i=1; i<=n; i++)
{
insert_delete(a[i],-1);
for(ll j=i+1; j<=n; j++)
{
insert_delete(a[j],-1);
ll temp=(a[i]+a[j]);
maxx=max(maxx,find_num(temp)^temp);
insert_delete(a[j],1);
}
insert_delete(a[i],1);
}
printf("%lld\n",maxx);
}
}