JIH的玩偶

题目描述
JIH的玩具厂设立以来,发展了一张销售关系网。这张网以玩具厂为总代理(根),构成一颗树。每个节点都代表一个客户,且每个节点都有重要度ai。JIH想将这些客户划成若干类别,当然同一类的客户重要度相差太大总是不妥。所以JIH决定先进行市场调研。JIH会选择两个客户X,从X向根走一共k个节点进行调查。调查的结果是这条路径上重要程度相差最大的两个客户的差值是多少。因为特殊需要,要求重要度大的客户必须在重要度小的客户后面(顺序为X到根,若序列为递减,则输出0,详情见样例)。
输入
第一行一个整数N 表示N个客户
第二行N个整数Ai 表示N个客户的重要程度(工厂是1)
第三行开始 共N-1行 每行2个整数 x,y 表示x的父亲是y
接着一行一个正整数Q,表示Q次调研
接着Q行,每行两个整数X,K。含义见题目表述。
输出
Q行,每行一个正整数,含义见题目描述。
样例输入
6
5 6 1 7 5 2
2 1
3 1
4 2
5 2
6 3
3
4 3
6 2
6 3
样例输出
0
0
4
提示
数据范围:
30% 的数据中N,Q<=1000
100%的数据中N,Q<=200000 Ai<=1000000

对于树上路径问题,我们采用倍增思想,记gmin[i,k],gmax[i,k],gans[i,k]分别表示i到i的2^k个父亲的最小值,最大值,与答案。对于答案的计算,对于预处理:
gans[i,k]:=max(gans[i,k-1],gans[f[i,k-1],k-1]);
gans[i,k]:=max(gans[i,k],gmax[f[i,k-1],k-1]-gmin[i,k-1]);
答案可能为两段答案的最大值,或者一段的最大值减另一段的最小值。
对于询问:
ans:=max(maxn-mini,max(gans[i,k],gans[j,k]));
答案可以是i到i+2^k这一段的gans,或j到j+2^k段的答案,或是i+2^k到j+2^k段的最大值-i到j段的最小值。

var
a:array[0..200022] of longint;
f,gmax,gmin,gans:array[0..200002,0..18] of longint;
n,i,u,v,k,q,x,r,jump,ans,mini,maxn,d:longint;
function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;

function min(a,b:longint):longint;
begin
  if a<b then exit(a) else exit(b);
end;

begin
  readln(n);
  for i:=1 to n do
    read(a[i]);
  readln;
  for i:=1 to n-1 do
  begin
    readln(v,u);
    f[v,0]:=u;
    gmax[v,0]:=max(a[v],a[u]);
    gmin[v,0]:=min(a[v],a[u]);
    gans[v,0]:=max(0,a[u]-a[v]);
  end;
  gmax[1,0]:=a[1];
  gmin[1,0]:=a[1];
  for k:=1 to 18 do
  begin
    for i:=1 to n do
    begin
      f[i,k]:=f[f[i,k-1],k-1];
      gmax[i,k]:=max(gmax[i,k-1],gmax[f[i,k-1],k-1]);
      gmin[i,k]:=min(gmin[i,k-1],gmin[f[i,k-1],k-1]);
      gans[i,k]:=max(gans[i,k-1],gans[f[i,k-1],k-1]);
      gans[i,k]:=max(gans[i,k],gmax[f[i,k-1],k-1]-gmin[i,k-1]);
    end;
  end;
  readln(q);
  for i:=1 to q do
  begin
    readln(u,x);
    x:=x-1;
    r:=0;
    for k:=18 downto 0 do
      if x>>k and 1=1 then begin r:=1<<k; break; end;
    ans:=0;
    jump:=x-r;
    v:=u;
    mini:=maxlongint;
    for d:=0 to 18 do
      if jump>>d and 1=1 then begin mini:=min(mini,gmin[v,d]); v:=f[v,d]; end;
    ans:=max(gans[u,k],gans[v,k]);
    v:=f[u,k];
    maxn:=0;
    for d:=0 to 18 do
      if jump>>d and 1=1 then begin maxn:=max(maxn,gmax[v,d]); v:=f[v,d]; end;
    ans:=max(maxn-mini,ans);
    writeln(ans);
  end;
end.
基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值