金题大战Vol.0 C、树上的等差数列

题目描述

给定一棵包含\(N\)个节点的无根树,节点编号\(1-N\)。其中每个节点都具有一个权值,第\(i\)个节点的权值是\(A_i\)。

小\(Hi\)希望你能找到树上的一条最长路径,满足沿着路径经过的节点的权值序列恰好构成等差数列。

输入格式

第一行包含一个整数\(N\)。

第二行包含\(N\)个整数\(A_1, A_2, ... A_N\)。

以下\(N-1\)行,每行包含两个整数\(U\)和\(V\),代表节点\(U\)和\(V\)之间有一条边相连。

输出格式

最长等差数列路径的长度

样例

样例输入

7

3 2 4 5 6 7 5

1 2

1 3

2 7

3 4

3 5

3 6

样例输出

4

数据范围与提示

对于\(50\%\)的数据,\(1 ≤ N ≤ 1000\)

对于\(100\%\)的数据,\(1 ≤ N ≤ 100000, 0 ≤ Ai ≤ 100000, 1 ≤ U, V ≤ N\)

分析

树形\(DP\)

我们设 \(f[i][j]\) 为以\(i\)作为根节点的子树中公差为\(j\)的路径的最长长度,接下来考虑转移

转移的过程无非是把子树中的状态递归至父亲节点

即 \(f[now][a[now]-a[u]]=max(f[now][a[now]-a[u]],f[u][a[now]-a[u]]+1)\)

其中 \(now\) 为父亲节点,\(u\)为儿子节点

统计答案时,我们只要在所有的\(f[now][val]+f[now][-val]+1\)中取最大值就可以了

其实就是把两条链拼在一起

加上一是为了防止特判一些奇奇怪怪的边界问题,比如说只有一个点的情况

要注意 \(0\) 的时候要特判一下,因为此时\(val\)和\(-val\) 相等,直接更新会出错

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
struct asd{
int from,to,next;
}b[maxn];
int head[maxn],tot=1,n,a[maxn],ans=0;
inline void ad(int aa,int bb){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
inline int read(){
register int x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
map<int,int>f[maxn];
void dfs(int now,int fa){
int max0=0;
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(u==fa) continue;
dfs(u,now);
if(a[u]==a[now]){
if(f[now][0]<=f[u][0]+1){
max0=f[now][0];
f[now][0]=f[u][0]+1;
}
else if(max0<f[u][0]+1) max0=f[u][0]+1;
ans=max(ans,f[now][0]+max0+1);
} else {
f[now][a[now]-a[u]]=max(f[now][a[now]-a[u]],f[u][a[now]-a[u]]+1);
ans=max(ans,f[now][a[now]-a[u]]+f[now][a[u]-a[now]]+1);
}
}
}
int main(){
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
memset(head,-1,sizeof(head));
n=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(register int i=1;i<n;i++){
register int aa,bb;
aa=read(),bb=read();
ad(aa,bb);
ad(bb,aa);
}
dfs(1,0);
printf("%d\n",ans);
return 0;
}

金题大战Vol.0 C、树上的等差数列的更多相关文章

  1. 金题大战Vol.0 A、凉宫春日的叹息

    金题大战Vol.0 A.凉宫春日的叹息 题目描述 给定一个数组,将其所有子区间的和从小到大排序,求第 \(k\) 小的是多少. 输入格式 第一行两个数\(n\),$ k\(,表示数组的长度和\)k$: ...

  2. 金题大战Vol.0 B、序列

    金题大战Vol.0 B.序列 题目描述 给定两个长度为 \(n\) 的序列\(a\), \(b\). 你需要选择一个区间\([l,r]\),使得\(a_l+-+a_r>=0\)且\(b_l+-+ ...

  3. 土题大战Vol.0 A. 笨小猴 思维好题

    土题大战Vol.0 A. 笨小猴 思维好题 题目描述 驴蛋蛋有 \(2n + 1\) 张 \(4\) 星武器卡片,每张卡片上都有两个数字,第 \(i\) 张卡片上的两个数字分别是 \(A_i\) 与 ...

  4. 火题大战Vol.0 B 计数DP

    火题大战Vol.0 B 题目描述 \(n\) 个沙茶,被编号 \(1\)~$ n$.排完队之后,每个沙茶希望,自己的相邻的两人只要无一个人的编号和自己的编号相差为 \(1\)(\(+1\) 或\(-1 ...

  5. 水题大战Vol.3 B. DP搬运工2

    水题大战Vol.3 B. DP搬运工2 题目描述 给你\(n,K\),求有多少个\(1\)到\(n\) 的排列,恰好有\(K\)个数\(i\) 满足\(a_{i-1},a_{i+1}\) 都小于\(a ...

  6. 火题大战Vol.1 A.

    火题大战Vol.1 A. 题目描述 给定两个数\(x\),\(y\),比较\(x^y\) 与\(y!\)的大小. 输入格式 第一行一个整数\(T\)表示数据组数. 接下来\(T\)行,每行两个整数\( ...

  7. [火星补锅] 水题大战Vol.2 T2 && luogu P3623 [APIO2008]免费道路 题解

    前言: 如果我自己写的话,或许能想出来正解,但是多半会因为整不出正确性而弃掉. 解析: 这题算是对Kruskal的熟练运用吧. 要求一颗生成树.也就是说,最后的边数是确定的. 首先我们容易想到一个策略 ...

  8. [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)

    前言: 当时考场上并没有想出来...后来也是看了题解才明白 解析: 大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化.(这个性质挺重要的,我之前没看出来) 所以就可以 ...

  9. MathExam小学一二年级计算题生成器V1.0

    MathExam小学一二年级计算题生成器v1.0 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning ...

随机推荐

  1. css:实现文本两行或多行文本溢出显示省略号

    div{ display: -webkit-box; -webkit-box-orient: vertical; word-break: break-all; word-wrap: break-wor ...

  2. 一款直击痛点的优秀http框架,让我超高效率完成了和第三方接口的对接

    1.背景 因为业务关系,要和许多不同第三方公司进行对接.这些服务商都提供基于http的api.但是每家公司提供api具体细节差别很大.有的基于RESTFUL规范,有的基于传统的http规范:有的需要在 ...

  3. Ubuntu Server 19.04配置静态IP

    这个/etc/netplan下默认有个文件50-cloud-init.yaml,直接修改它就行了 sudo vim /etc/netplan/50-cloud-init.yaml 网口名字enp0s3 ...

  4. vue的自定义指令。directive

    在vue中有很多vue自带的指令,比如v-heml.v-for.v-if,v-on.v-bind.v-else.v-show. 但是这些指令还不够我们使用的.就有了directive这个对象. 这个使 ...

  5. [难题题解] [BZOJ1875] [SDOI2009] HH去散步

    题目H有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人 ...

  6. Dom运用2

    1.登录系统 <!--输入框创建--> 账号:<input class="ipt" type="text"><br> 密码: ...

  7. 解释Crypto模块,No module named "Crypto"

    1.pip install pycryptodome 2.Python\Python38\Lib\site-packages,找到这个路径,下面有一个文件夹叫做crypto,将小写c改成大写C就ok了 ...

  8. setTimeout、clearTimeout、setInterval

    setTimeout(cb, ms) setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb).:setTimeout() 只执行一次指定函数. 返回一个代表定时器的 ...

  9. Python os.minor() 方法

    概述 os.minor() 方法用于从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field ).高佣联盟 www.cgewang.com 语法 minor ...

  10. 原生JS 实现点击按钮创建元素

    要求: 点击按钮,随机生成一个20px-100px宽度正方形,随机颜色,随机位置,不能出可视区域外 思路:(1)创建按钮,为按钮添加事件侦听 (2)触发事件,创建一个元素 (3)设置元素样式,包括大小 ...