1 条题解

  • 0
    @ 2023-10-12 16:29:19

    另一道字典树的趣题。

    模拟一下算路径上异或和的过程,我们发现对于两个节点 xxyyxxyy 路径上的异或和 =(x=(x 到根节点路径的异或和 )(y)⨁(y 到根节点的异或和 )) ,这就转化成了 「一本通 2.3 练习 5」The Xor-longest Path - HydroOJ 原题,我们求的就是 (任意两条到根节点的路径的异或和的) 异或最大值。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100005
    #define S 3200005
    #define M 200005
    int ch[S][2],n,a[N],tot,ans,cnt;
    int fir[N],to[M],nxt[M],w[M],xorx[N];
    void add(int x,int y,int z){
    	nxt[++cnt]=fir[x];
    	fir[x]=cnt;
    	to[cnt]=y;
    	w[cnt]=z;
    }
    void write(int x){
    	if(x>=2)write(x>>1);
    	putchar((x&1)+'0');
    }
    void insert(int num,int x=0){
    	for(int i=1;i<=31;++i){
    		short c=((num&0x40000000)>>30);
    		if(ch[x][c]==0)ch[x][c]=++tot;
    		x=ch[x][c];
    		num<<=1;
    	}
    }
    int search(int num,int x=0,int ret=0){
    	for(int i=1;i<=31;++i){
    		short c=1-((num&0x40000000)>>30);
    		if(ch[x][c]==0){
    			ret<<=1;
    			c=1-c;
    		}else ret=((ret<<1)|1);
    		x=ch[x][c];
    		num<<=1;
    	}
    	return ret;
    }
    void dfs(int x,int fa){
    	for(int e=fir[x];e;e=nxt[e]){
    		int u=to[e];
    		if(u==fa)continue;
    		xorx[u]=xorx[x]^w[e];
    		dfs(u,x);
    	}
    }
    int main(){
    	int x,y,z;
    	scanf("%d",&n);
    	for(int i=1;i<n;++i){
    		scanf("%d %d %d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;++i){
    //		printf("x[%d]=%d\n",i,xorx[i]);
    		insert(xorx[i]);
    	}
    	for(int i=1;i<=n;++i){
    		ans=max(ans,search(xorx[i]));
    	}
    	printf("%d",ans);
    	return 0;
    }
    
    • 1

    「一本通 2.3 练习 5」The Xor-longest Path

    信息

    ID
    467
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    (无)
    递交数
    2
    已通过
    1
    上传者