Stars_visitor_tyw
2024-05-10 22:52:02
从数据范围很容易发现,如果我们把边权累乘再判整数,炸掉是必然的,这时候,我们来发现一个性质:只有小数部分有
注意:若边权或点权为
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
const int inf=1e16;
struct node
{
int y, w, dlp;//dlp表示小数点位数,Decimal Places
};
int n, m, s, dep[N], dp[N][21], dis[N], cnt2[N], cnt5[N], a[N];
vector<node> nbr[N];
int count_two(int x)
{
if(x==0)
{
return inf;
}
int cnt=0;
while(x!=0&&x%2==0)
{
cnt++;
x/=2;
}
return cnt;
}
int count_five(int x)
{
if(x==0)
{
return inf;
}
int cnt=0;
while(x!=0&&x%5==0)
{
cnt++;
x/=5;
}
return cnt;
}
void pre_lca(int cur, int fa)
{
dp[cur][0]=fa;
dep[cur]=dep[fa]+1;
for(int i=1;(1<<i)<=dep[cur];i++)
{
dp[cur][i]=dp[dp[cur][i-1]][i-1];
}
for(auto i:nbr[cur])
{
int nxt=i.y;
if(nxt!=fa)
{
dis[nxt]=dis[cur]+i.dlp,cnt2[nxt]=cnt2[cur]+count_two(i.w),cnt5[nxt]=cnt5[cur]+count_five(i.w);
pre_lca(nxt,cur);
}
}
}
int lca(int x, int y)
{
if(dep[x]>dep[y])
{
swap(x,y);
}
for(int i=20;i>=0;i--)
{
if(dep[x]<=dep[dp[y][i]])
{
y=dp[y][i];
}
}
if(x==y)
{
return x;
}
for(int i=20;i>=0;i--)
{
if(dp[x][i]!=dp[y][i])
{
x=dp[x][i];
y=dp[y][i];
}
}
return dp[x][0];
}
signed main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
int x, y;
double v;
cin>>x>>y>>v;
int dlp=0;
while(v!=floor(v))
{
v*=10.0;
dlp++;
}
nbr[x].push_back((node){y,floor(v),dlp});
nbr[y].push_back((node){x,floor(v),dlp});
}
pre_lca(1,0);
for(;m;m--)
{
int x, y;
cin>>x>>y;
int tmp=lca(x,y);
if(min(cnt2[x]+cnt2[y]-2*cnt2[tmp]+count_two(a[x]),cnt5[x]+cnt5[y]-2*cnt5[tmp]+count_five(a[x]))>=dis[x]+dis[y]-2*dis[tmp])
{
cout<<"Yes\n";
}
else
{
cout<<"No\n";
}
}
}