[luogu2420] 让我们异或吧 {dfs+异或}

版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88593112

题目

https://www.luogu.org/problemnew/show/P1351


解题思路

x , y l c a , . {\color{Purple} 这道题目最纯粹的思路应该是求x,y的lca,然后累计异或和.}
需要知道一个关于 x o r xor 的知识: x y y = x ( y y ) x \oplus y\oplus y = x\oplus ( y \oplus y )
因为 y y = 0 {\color{Red} y \oplus y=0}

d i s [ t ] t {\color{Red}{dis[t]}}表示根节点到t的异或路径和

答案易得 ( d i s [ x ] d i x [ l c a ] ) ( d i s [ y ] d i s [ l c a ] ) {\color{Purple} (dis[x] \oplus dix[lca]) \oplus (dis[y]\oplus dis[lca]) }

简化一下就变成了 ( d i s [ x ] d i x [ l y ] ) ( d i s [ l c a ] d i s [ l c a ] ) {\color{Purple} (dis[x] \oplus dix[ly]) \oplus (dis[lca]\oplus dis[lca]) }

就是 d i s [ x ] d i x [ l y ] {\color{Purple} dis[x] \oplus dix[ly] }


代码

#include<cstdio>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std;
struct node{int y,z,next;}a[200005];
int g,n,head[100001],dis[100001],tot; 
void add(int x,int y,int z){a[++tot]=(node){y,z,head[x]};head[x]=tot;}
void dfs(int x,int fa){
	for(register int i=head[x];i;i=a[i].next){
		int y=a[i].y; 
		if (y!=fa){
			dis[y]=dis[x]^a[i].z; 
			dfs(y,x); 
		}
	}
}
int main(){
	scanf("%d",&n); 
	int x,y,z; 
	rep(i,1,n-1) 
	 scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z); 
	dfs(1,0); 
	scanf("%d",&g); 
	rep(i,1,g) scanf("%d%d",&x,&y),printf("%d\n",dis[x]^dis[y]); 
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/88593112