1. 程式人生 > 實用技巧 >HIT第二週 周測補題

HIT第二週 周測補題

A ARK

E Everspace

F Fallout

H Halo

異或知識+tries樹

計算從根節點到每個點的異或距離,再從中找出兩個異或後值最大的即可。

#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 100100
using namespace std;
typedef long long ll;
struct node
{
    int to,nxt,w;
}e[maxn*2];
int num,last[maxn],ch[maxn*32][2],cnt;
ll f[maxn],note[maxn
*32]; void add(int x,int y,int z) { e[++num].to=y; e[num].nxt=last[x]; last[x]=num; e[num].w=z; } void build(ll now) { int i,u=0,x; for (i=31;i>=0;i--) { x=(now>>i)&1; if (!ch[u][x]) ch[u][x]=++cnt; u=ch[u][x]; } note[u]=now; } ll find(ll now) {
int i,u=0,x; for (i=31;i>=0;i--) { x=(now>>i)&1; if (ch[u][x^1]) u=ch[u][x^1]; else u=ch[u][x]; } return note[u]; } void dfs(int fa,int x) { for (int i=last[x];i!=-1;i=e[i].nxt) { if (e[i].to==fa) continue; f[e[i].to]=f[x]^e[i].w; dfs(x,e[i].to); } }
int main() { int n,x,y,z,i; ll tmp,ans; while (scanf("%d",&n)!=EOF) { memset(last,-1,sizeof(last)); memset(f,0,sizeof(f)); memset(ch,0,sizeof(ch)); memset(note,0,sizeof(note)); num=0;cnt=0;ans=0; for (i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } build(0); dfs(0,0); for (i=0;i<n;i++) build(f[i]); for (i=0;i<n;i++) { tmp=find(f[i])^f[i]; if (tmp>ans) ans=tmp; } printf("%lld\n",ans); } return 0; }

I Icey

J Just Cause

K Kerbal Space Program