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);
	}
}


转载于:https://www.cnblogs.com/Extended-Ash/p/7774407.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值