wa on2求条
查看原帖
wa on2求条
690243
houluyu楼主2024/8/27 13:40
#include<bits/stdc++.h>
#define f first
#define s second
#define pii pair<int, int>  
#define int long long
using namespace std;

const int inf = 10000000, N = 501005;
int n, m, a[N], anc[N][22], p[N]; //p是从根来的路径 
int dep[N], ans[N]; 
int t[inf + 5], val[N];//t[i]到u的时候存了根到u,i出现了多少次 
vector<vector<int> > g(N);
vector<vector<pii> > g1(N);

void dfs(int u, int fa)
{
	for(int i = 1; i <= 20; i ++)
	{
		anc[u][i] = anc[anc[u][i - 1]][i - 1];
	}
	for(int i = 0; i < g[u].size(); i ++)
	{
		int v = g[u][i];
		if(v == fa)continue;
		anc[v][0] = u;
		p[v] = p[u] ^ a[v];
		dep[v] = dep[u] + 1;
		dfs(v, u);
	}
	return ;
}

int lca(int x, int y)
{
	if(dep[x] < dep[y])swap(x, y);
	for(int i = 20; i >= 0; i --)
	{
		if(dep[x] - (1 << i) >= dep[y])
		{
			x = anc[x][i];
		}
	}
	if(x == y)return x;
	for(int i = 20; i >= 0; i --)
	{
		if(anc[x][i] != anc[y][i])
		{
			x = anc[x][i];
			y = anc[y][i];
		}
	}
	return anc[x][0];
}
void dfs1(int u, int fa)
{
	t[a[u]] ++;
	for(int i = 0; i < g1[u].size(); i ++)//对于所有问题 
	{
		int q = g1[u][i].f, gx = g1[u][i].s; 
		ans[q] += gx * t[val[q]];
	} 
	for(int i = 0; i < g[u].size(); i ++)
	{
		int v = g[u][i];
		if(v == fa)continue;
		dfs1(v, u); 
	}
	t[a[u]] --;//要换成fa的另一条分支了 
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	scanf("%lld%lld", &n, &m);
	for(int i = 1; i <= n; i ++)
	{
		scanf("%lld", & a[i]);
	}
	for(int i = 1; i < n; i ++)
	{
		int u, v;
		scanf("%lld%lld", &u, &v);
		g[u].push_back(v);
		g[v].push_back(u); 
	}
	p[1] = a[1]; 
	dep[1] = 1;
	dfs(1, 0);
//	for(int i = 1; i <= n; i ++)cout << i << ' ' << anc[i][0] << ' ' << anc[i][1] << ' ' << anc[i][2] << endl; 
	for(int i = 1; i <= m; i ++)
	{
		int u, v, k;
//		cin >> u >> v >> k;
		scanf("%lld%lld%lld", &u, &v, &k);
		if(k > inf)continue;
		int zx = lca(u, v);
		val[i] = k ^ p[u] ^ p[v] ^ a[zx];
//		cout << zx << endl;
		g1[u].push_back({i, 1});
		g1[v].push_back({i, 1});
		g1[zx].push_back({i, -1});
		g1[anc[zx][0]].push_back({i, -1});
	}
	dfs1(1, 0);
	for(int i = 1; i <= m; i ++)
	{
		if(ans[i] > 0)printf("Yes\n");
		else printf("No\n"); 
//		cout << (ans[i] > 0 ? "Yes" : "No") << endl;
	}
	return 0;
}
2024/8/27 13:40
加载中...