思路:树上倍增f[i][j]=f[f[i][j-1]][j-1]还有LCA的赶脚
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <set>
#include <sstream>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#include<cctype>
#include<cstring>
#include<cstdlib>
#define MAXX 100005
#define SIS std::ios::sync_with_stdio(false)
#define ll long long
#define INF 0x3f3f3f3f
//#include<bits/stdc++.h>
using namespace std;
const int MAX =1e5+20;
const double PI = 3.14159265359;
//const int mod = 1e9 + 7;
int a[200005],b[200005];
vector<int> vt[200005];
int f[200005][25],dep[200005];
void dfs(int p,int fa)
{
int x=fa;
for(int k=19;k>=0;k--)
{
if(f[x][k]&&a[f[x][k]]<=a[p])///如果x往上跳2^k步这个点存在,且这个点的权值比a[p]要小,就跳到这个点再往上跳
x=f[x][k];
}
if(a[x]>a[p]) f[p][0]=x; ///判断比a[p]大的点到底是x还是x的上面那个点
else f[p][0]=f[x][0];
for(int i=1;i<20;i++)
f[p][i]=f[f[p][i-1]][i-1];
dep[p]=dep[fa]+1;
int h=vt[p].size();
for(int i=0;i<h;i++)
{
int u=vt[p][i];
if(u==fa) continue;
dfs(u,p);
}
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
vt[x].push_back(y);
vt[y].push_back(x);
}
for(int i=1;i<=q;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
vt[n+i].push_back(u);
vt[u].push_back(n+i);
a[n+i]=c;
b[i]=v;///终点
}
dfs(1,0);
for(int i=1;i<=q;i++)
{
int ans=0;
int x=i+n;
for(int k=19;k>=0;k--)
if(dep[f[x][k]]>=dep[b[i]])
{
ans+=(1<<k);
x=f[x][k];
}
printf("%d\n",ans);
}
return 0;
}

京公网安备 11010502036488号