RT,WA on #5,其余TLE
#include <bits/stdc++.h>
using namespace std;
const int N = 200000;
int n;
int node_two[N + 1], node_five[N + 1], side[N + 1], side_two[N + 1], side_five[N + 1];
long long t[N << 2], t_two[N << 2], t_five[N << 2], d[N << 2], d_two[N << 2], d_five[N << 2];
int son[N + 1], fa[N + 1], head[N + 1], sz[N + 1], depth[N + 1], dfn[N + 1], ddfn[N + 1], tot;
struct Tjaweiof{
int v, w, w_two, w_five;
};
vector <Tjaweiof> e[N + 1];
void pushup(int x){
t[x] = t[x << 1] + t[x << 1 | 1];
t_two[x] = t_two[x << 1] + t_two[x << 1 | 1];
t_five[x] = t_five[x << 1] + t_five[x << 1 | 1];
return;
}
void build(int x, int L, int R){
if (L == R){
t[x] = side[ddfn[L]];
t_two[x] = side_two[ddfn[L]];
t_five[x] = side_five[ddfn[L]];
return;
}
int mid = (L + R) >> 1;
build(x << 1, L, mid);
build(x << 1 | 1, mid + 1, R);
pushup(x);
return;
}
long long query(int x, int l, int r, int L, int R){
if (l == L && r == R){
return t[x];
}
int mid = (L + R) >> 1;
if (r <= mid){
return query(x << 1, l, r, L, mid);
} else if (l > mid){
return query(x << 1 | 1, l, r, mid + 1, R);
} else {
return query(x << 1, l, mid, L, mid) + query(x << 1 | 1, mid + 1, r, mid + 1, R);
}
}
long long query_two(int x, int l, int r, int L, int R){
if (l == L && r == R){
return t_two[x];
}
int mid = (L + R) >> 1;
if (r <= mid){
return query_two(x << 1, l, r, L, mid);
} else if (l > mid){
return query_two(x << 1 | 1, l, r, mid + 1, R);
} else {
return query_two(x << 1, l, mid, L, mid) + query_two(x << 1 | 1, mid + 1, r, mid + 1, R);
}
}
long long query_five(int x, int l, int r, int L, int R){
if (l == L && r == R){
return t_five[x];
}
int mid = (L + R) >> 1;
if (r <= mid){
return query_five(x << 1, l, r, L, mid);
} else if (l > mid){
return query_five(x << 1 | 1, l, r, mid + 1, R);
} else {
return query_five(x << 1, l, mid, L, mid) + query_five(x << 1 | 1, mid + 1, r, mid + 1, R);
}
}
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;
}
dfs1(u.v, x, dep + 1);
side[u.v] = u.w;
side_two[u.v] = u.w_two;
side_five[u.v] = u.w_five;
if (sz[u.v] > sz[son[x]]){
son[x] = u.v;
}
sz[x] += sz[u.v];
}
return;
}
void dfs2(int x, int he){
tot++;
dfn[x] = tot;
ddfn[tot] = x;
if (son[x]){
dfs2(son[x], he);
}
for (auto u : e[x]){
if (u.v == son[x] || u.v == fa[x]){
continue;
}
dfs2(u.v, u.v);
}
return;
}
long long query_path(int u, int v){
long long res = 0;
while (head[u] != head[v]){
if (depth[head[u]] < depth[head[v]]){
swap(u, v);
}
res += query(1, dfn[head[u]], dfn[u], 1, n);
u = fa[head[u]];
}
if (depth[u] > depth[v]){
swap(u, v);
}
if (u == v){
return res;
}
res += query(1, dfn[u] + 1, dfn[v], 1, n);
return res;
}
long long query_path_two(int u, int v){
long long res = 0;
while (head[u] != head[v]){
if (depth[head[u]] < depth[head[v]]){
swap(u, v);
}
res += query_two(1, dfn[head[u]], dfn[u], 1, n);
u = fa[head[u]];
}
if (depth[u] > depth[v]){
swap(u, v);
}
if (u == v){
return res;
}
res += query_two(1, dfn[u] + 1, dfn[v], 1, n);
return res;
}
long long query_path_five(int u, int v){
long long res = 0;
while (head[u] != head[v]){
if (depth[head[u]] < depth[head[v]]){
swap(u, v);
}
res += query_five(1, dfn[head[u]], dfn[u], 1, n);
u = fa[head[u]];
}
if (depth[u] > depth[v]){
swap(u, v);
}
if (u == v){
return res;
}
res += query_five(1, dfn[u] + 1, dfn[v], 1, n);
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int q;
cin >> n >> q;
for (int i = 1; i <= n; i++){
int a;
cin >> a;
if (a){
while (a % 2 == 0){
node_two[i]++;
a = a >> 1;
}
while (a % 5 == 0){
node_five[i]++;
a /= 5;
}
} else {
node_two[i] = 1000000000;
node_five[i] = 1000000000;
}
}
for (int i = 1; i < n; i++){
int u, v;
double w;
cin >> u >> v >> w;
int w_ = 0, w_two = 0, w_five = 0;
while ((int)w != w){
w *= 10;
w_++;
}
int ww = w;
if (ww){
while (ww % 2 == 0){
w_two++;
ww = ww >> 1;
}
while (ww % 5 == 0){
w_five++;
ww /= 5;
}
} else {
w_two = 1000000000;
w_five = 1000000000;
}
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);
build(1, 1, n);
while (q--){
int u, v;
cin >> u >> v;
// cout << query_path(u, v) << " " << query_path_two(u, v) << " " << query_path_five(u, v) << endl;
if (query_path(u, v) <= min(node_two[u] + query_path_two(u, v), node_five[u] + query_path_five(u, v))){
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
}
return 0;
}