版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/82668840
额树形DP+ST表倍增
按照区间最长链的思路树形DP
ST表倍增(我写的有点丑)
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=1e5+100;
struct Front_star{
int u,v,w,nxt;
}e[N<<2];
int cnt=0;
int first[N];
void add(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
int n,m,a,b,c;
int F[N][2];
int son[N];
int dep[N]={};
int fa[N][21];
int st[N][21];
void DFS1(int u,int fat){
fa[u][0]=fat;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fat)continue;
dep[v]=dep[u]+1;
DFS1(v,u);
if(F[v][0]+e[i].w>F[u][0]){
F[u][1]=F[u][0];
F[u][0]=F[v][0]+e[i].w;
son[u]=v;
}
else
if(F[v][0]+e[i].w>F[u][1]){
F[u][1]=F[v][0]+e[i].w;
}
}
}
int G[N];
void DFS2(int u,int fat,int len){
if(u!=son[fat]){
G[u]=max(G[u],F[fat][0]);
}
else{
G[u]=max(G[u],F[fat][1]);
}
G[u]=max(G[u],G[fat])+len;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fat)continue;
DFS2(v,u,e[i].w);
}
}
int val[N]={};
void Pre(){
for(int i=1;i<=n;++i)st[i][0]=val[fa[i][0]];
for(int i=1;i<=20;++i){
for(int j=1;j<=n;++j){
fa[j][i]=fa[fa[j][i-1]][i-1];
st[j][i]=max(st[fa[j][i-1]][i-1],st[j][i-1]);
}
}
}
int GetLCA(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=fa[x][i];
}
if(x==y)return x;
for(int i=20;i>=0;i--){
if(fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
int GetLow(int x,int d,int LCA,int Q){
if(dep[x]<=dep[LCA])return -1;
for(;dep[fa[x][d]]<dep[LCA]&&d;d--);
if(st[x][d]<Q)return GetLow(fa[x][d],d-1,LCA,Q);
for(int i=d-1;i>=0;i--){
if(st[x][i]<Q){
x=fa[x][i];
}
}
return fa[x][0];
}
int GetHigh(int x,int d,int LCA,int Q){
if(dep[x]<=dep[LCA])return -1;
for(;dep[fa[x][d]]<dep[LCA]&&d;d--);
int ret=GetHigh(fa[x][d],d-1,LCA,Q);
if(~ret)return ret;
if(st[x][d]<Q)return -1;
for(int i=d-1;i>=0;i--){
if(st[fa[x][i]][i]>=Q)x=fa[x][i];
}
return fa[x][0];
}
INT main(){
// freopen("test.in","r",stdin);
read(n);
read(m);
read(a);
read(b);
read(c);
for(int i=1;i<n;++i){
int u,v,w;
read(u);
read(v);
read(w);
add(u,v,w);
add(v,u,w);
}
DFS1(1,0);
DFS2(1,0,0);
for(int i=1;i<=n;++i)val[i]=(max(G[i],F[i][0])+a)*b%c;
Pre();
while(m--){
int u,v,q;
read(u);
read(v);
read(q);
int LCA=GetLCA(u,v);
// cout<<LCA<<'\n';
int ans=-1;
if(val[u]>=q){
ans=u;
}
if(ans==-1){
int d=0;
for(;(1<<d)<=dep[u];++d);
d--;
ans=GetLow(u,d,LCA,q);
}
if(ans==-1){
int d=0;
for(;(1<<d)<=dep[v];++d);
d--;
ans=GetHigh(v,d,LCA,q);
}
if(ans==-1&&val[v]>=q)ans=v;
cout<<ans<<'\n';
}
}