还是0pts求助,悬赏一关
查看原帖
还是0pts求助,悬赏一关
550933
Tjaweiof楼主2024/4/9 09:41

根据 此帖 巨佬的建议,我重新写了一遍,换了一种方法(纯树剖 →\rightarrow 树剖求 lcalca),但是还是不行。

提交记录(小号提交)

#include <bits/stdc++.h>
using namespace std;
int fa[200001], depth[200001], sz[200001], head[200001], son[200001];
struct Tjaweiof{
	int w, w_two, w_five;
}sum[200001], val[200001];
struct Tjaweiof2{
	int v, w, w_two, w_five;
};
vector <Tjaweiof2> e[200001];
void dfs1(int x, int father, int dep){
	fa[x] = father;
	depth[x] = dep;
	sz[x] = 1;
	for (auto u : e[x]){
		if (u.v == father){
			continue;
		}
		sum[u.v].w = sum[x].w + u.w;
		sum[u.v].w_two = sum[x].w_two + u.w_two;
		sum[u.v].w_five = sum[x].w_five + u.w_five;
		dfs1(u.v, x, dep + 1);
		sz[x] += sz[u.v];
		if (sz[u.v] > sz[son[x]]){
			son[x] = u.v;
		}
	}
	return;
}
void dfs2(int x, int he){
	head[x] = he;
	if (son[x]){
		dfs2(son[x], he);
	}
	for (auto u : e[x]){
		if (u.v == fa[x] || u.v == son[x]){
			continue;
		}
		dfs2(u.v, u.v);
	}
	return;
}
int lca(int u, int v){
	while (head[u] != head[v]){
		if (depth[head[u]] < depth[head[v]]){
			swap(u, v);
		}
		u = fa[head[u]];
	}
	if (depth[u] > depth[v]){
		return v;
	} else {
		return u;
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, q, u, v;
	long long x;
	double w;
	cin >> n >> q;
	for (int i = 1; i <= n; i++){
		cin >> x;
		if (!x){
			val[i].w_two = 2147483647;
			val[i].w_five = 2147483647;
			continue;
		}
		while (x % 2 == 0){
			val[i].w_two++;
			x = x >> 1;
		}
		while (x % 5 == 0){
			val[i].w_five++;
			x /= 5;
		}
	}
	for (int i = 1; i < n; i++){
		cin >> u >> v >> w;
		int ww, w_ = 0, w_two = 0, w_five = 0;
		if (!w){
			w_two = 2147483647;
			w_five = 2147483647;
			continue;
		} else {
			while (w != (int)w){
				w *= 10;
				w_++;
			}
			ww = w;
			while (ww % 2 == 0){
				w_two++;
				ww = ww >> 1;
			}
			while (ww % 5 == 0){
				w_five++;
				ww /= 5;
			}
		}
		e[u].push_back({v, w_, w_two, w_five});
		e[v].push_back({u, w_, w_two, w_five});
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	while (q--){
		cin >> u >> v;
		int l = lca(u, v);
		if (sum[u].w + sum[v].w - (sum[l].w << 1) <= min(val[u].w_two + sum[u].w_two + sum[v].w_two - (sum[l].w_two << 1), val[u].w_five + sum[u].w_five + sum[v].w_five - (sum[l].w_five << 1))){
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}
	return 0;
}
2024/4/9 09:41
加载中...