P10471 最大异或对 The XOR Largest Pair - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
模板题,从最高位开始建立01字典树,查询时也从高位开始查,贪心思想遇到不一样的就走,没有就走一样的,就能保证走完的路径是这个数能组成的最大异或和。注意trie的空间范围:
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int n,trie[N][2],a[100001],tot,ans,anss;
void insert(int x)
{
bitset<32> s;
s=x;
int p=0;
for(int i=30;i>=0;i--)
{
int ch=s[i];
if(!trie[p][ch]) trie[p][ch]=++tot;
p=trie[p][ch];
}
}
int search(int x)
{
bitset<32> s;
s=x;
int p=0;
ans=0;
for(int i=30;i>=0;i--)
{
int ch=s[i];
if(trie[p][1-ch])
{
p=trie[p][1-ch];
ans+=(1<<i);
}
else p=trie[p][ch];
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
insert(a[i]);
}
for(int i=1;i<=n;i++)
{
anss=max(anss,search(a[i]));
}
cout<<anss;
}
P4551 最长异或路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
根据异或的基本性质不难发现,x到y的异或和就是x到根节点的异或和异或y到根节点的异或和,求出所有节点的异或和,从高位插入字典树中,再从高位查询,和上道题一样,遇到不一样的就走。
#include<bits/stdc++.h>
using namespace std;
const int N=100001,M=1e7+10;
int n,d[N],trie[M][2],anss;
int ver[N*2],Next[N*2],edge[N*2],head[N],tot;
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z;
Next[tot]=head[x],head[x]=tot;
}
void dfs(int x,int fa)
{
for(int i=head[x];i;i=Next[i])
{
int y=ver[i],z=edge[i];
if(y==fa) continue;
d[y]=d[x]^z;
dfs(y,x);
}
}
void insert(int x)
{
int p=0;
for(int i=30;i>=0;i--)
{
int ch=(x>>i)&1;
if(!trie[p][ch]) trie[p][ch]=++tot;
p=trie[p][ch];
}
}
int search(int x)
{
int p=0,ans=0;
for(int i=30;i>=0;i--)
{
int ch=(x>>i)&1;
if(trie[p][1-ch])
{
ans+=(1<<i);
p=trie[p][1-ch];
}
else p=trie[p][ch];
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z),add(y,x,z);
}
dfs(1,-1);
for(int i=1;i<=n;i++)
{
insert(d[i]);
anss=max(anss,search(d[i]));
}
printf("%d",anss);
}