Jzoj3523 JIH的玩偶
JIH的玩具厂设立以来,发展了一张销售关系网。这张网以玩具厂为总代理(根),构成一颗树。每个节点都代表一个客户,且每个节点都有重要度ai。JIH想将这些客户划成若干类别,当然同一类的客户重要度相差太大总是不妥。所以JIH决定先进行市场调研。JIH会选择两个客户X,从X向根走一共k个节点进行调查。调查的结果是这条路径上重要程度相差最大的两个客户的差值是多少。因为特殊需要,要求重要度大的客户必须在重要度小的客户后面(顺序为X到根)
这个题没有修改,只是从节点到根,所以简单的倍增即可
维护区间最大,最小和答案,那么Ans[x][j]=max(Ans[x][j-1],Ans[f[x]][j-1],Max[f[x]][j-1]-Min[x][j-1])
#include<stdio.h> #include<string.h> #include<algorithm> #define N 200010 using namespace std; int f[19][N],mn[19][N]; int mx[19][N],r[19][N]; int n,m; int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); scanf("%d",&n); mn[0][0]=1<<29; for(int i=1;i<=n;++i){ scanf("%d",mx[0]+i); mn[0][i]=mx[0][i]; } for(int a,b,i=1;i<n;++i){ scanf("%d%d",&a,&b); f[0][a]=b; } for(int i=1;i<=18;++i) for(int j=1;j<=n;++j){ f[i][j]=f[i-1][f[i-1][j]]; int p=f[i-1][j]; mx[i][j]=max(mx[i-1][j],mx[i-1][p]); mn[i][j]=min(mn[i-1][j],mn[i-1][p]); r[i][j]=max(max(0,mx[i-1][p]-mn[i-1][j]),max(r[i-1][j],r[i-1][p])); } scanf("%d",&m); for(int x,k,i=0;i<m;++i){ int _mx=0,_mn=1<<29,_r=0; scanf("%d%d",&x,&k); for(int j=0;k;++j,k>>=1) if(k&1){ _r=max(_r,max(r[j][x],mx[j][x]-_mn)); _mx=max(_mx,mx[j][x]); _mn=min(_mn,mn[j][x]); x=f[j][x]; } printf("%d\n",_r); } }