根据 此帖 巨佬的建议,我重新写了一遍,换了一种方法(纯树剖 → 树剖求 lca),但是还是不行。
#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;
}