思路:
很容易想到倍增,维护一个max和min还有ans,之后统计就行了
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
int n, f[200100][40], maxx[200100][40], minn[200100][40], ans[200100][40];
int a[1001010];
int main()
{
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
scanf("%d", &n);
minn[0][0]=1e9;
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
maxx[i][0]=a[i];
minn[i][0]=a[i];
}
for(int i=1; i<n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
f[x][0]=y;
}
for(int j=1; j<=18; j++)
for(int i=1; i<=n; i++)
{
f[i][j]=f[f[i][j-1]][j-1];
int k=f[i][j-1];
maxx[i][j]=max(maxx[i][j-1], maxx[k][j-1]);
minn[i][j]=min(minn[i][j-1], minn[k][j-1]);
ans[i][j]=max(0, max(maxx[k][j-1]-minn[i][j-1], max(ans[i][j-1], ans[k][j-1])));
}
int q;
scanf("%d", &q);
while(q--)
{
int x, k;
scanf("%d%d", &x, &k);
int ans1=0, minn1=1e9;
for(int j=0; k; j++, k>>=1)
{
if(k&1)
{
ans1=max(ans1, max(ans[x][j], maxx[x][j]-minn1));
minn1=min(minn1, minn[x][j]);
x=f[x][j];
}
}
printf("%d\n", ans1);
}
return 0;
}