很好的题呢

n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次:

1.R点跳到子树内

2.B点跳到下一层的任意节点

3.交换(R,B)[选做]

每次操作结束时,加上上abs(a[R所在点]-a[B所在点])

  • 思路:这样每层都是一个子问题,而且每次抉择都会影响下一个子问题,所以这个没办法贪心,于是考虑树上dp。

    dp[i]:表示R在i结点,第dep[i]~D层总最大价值和

    不交换:\(dp[u]=max(dp[v])+abs(a[u]-a[u'])\) 其中\(v\)是\(u\)的儿子。

    交换: \(dp[u]=max(dp[v']+abs(a[u]-a[u']))\) 其中\(v'\)是\(u'\)的儿子。

    若只有第一个式子就很好求,考虑第二个式子:

    \(v'\)跟\(u'\)是联系起来的,于是拆abs括号,改为\(max(dp[v']-a[u']+a[u],dp[v']+a[u']-a[u])\)

    然后我们就需要知道类似同层v'的mxson,然后按上面存一下。

    于是先dfs一遍,记录每层信息。

    再按层从下往上便历求解dp
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
typedef long long ll;
ll dp[N],a[N],mx[N],mn0[N],mx0[N];
int D,nxt[N],head[N],fa[N],to[N],ecnt,dep[N],cnt;
vector<int> V[N];
void add_edge(int u,int v) {nxt[++ecnt]=head[u];to[ecnt]=v;head[u]=ecnt;}
void dfs1(int u) {
dep[u]=dep[fa[u]]+1;
cnt++;
mx0[dep[u]]=max(mx0[dep[u]],a[u]);
mn0[dep[u]]=min(mn0[dep[u]],a[u]);
V[dep[u]].push_back(u);
D=max(D,dep[u]);
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa[u])continue;
fa[v]=u;
dfs1(v);
}
}
void solve() {
for(int i=D;i>=1;i--) {
ll mx1=-1e18,mx2=-1e18;
for(int q=0;q<V[i].size();q++) {
int u=V[i][q],w=max(abs(a[u]-mx0[dep[u]]),abs(a[u]-mn0[dep[u]]));
if(i==D) {dp[u]=w;continue;}
for(int j=head[u];j;j=nxt[j]) {
int v=to[j];
if(v==fa[u])continue;
mx[u]=max(mx[u],dp[v]);
dp[u]=max(dp[u],dp[v]+w);
}
mx1=max(mx1,mx[u]+a[u]);
mx2=max(mx2,mx[u]-a[u]);
}
if(i!=D) {
for(int q=0;q<V[i].size();q++) {
int u=V[i][q];
dp[u]=max(dp[u],max(mx1-a[u],a[u]+mx2));
// printf("%d: %lld\n",u,dp[u]);
}
}
V[i].clear();
}
}
int main() {
int T,n;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
ecnt=0;
for(int i=1;i<=n;i++) mn0[i]=1e9,dp[i]=head[i]=mx0[i]=mx[i]=0;
for(int i=2;i<=n;i++) {
int v;
scanf("%d",&v);
add_edge(i,v),add_edge(v,i);
}
for(int i=2;i<=n;i++) scanf("%lld",&a[i]);
dfs1(1);
solve();
printf("%lld\n",dp[1]);
}
return 0;
}

CF1485E Move and Swap的更多相关文章

  1. swap的几点理解

    一.什么是swap space(交换分区)? 在Linux系统中,当物理内存满了才使用Swap空间.当系统需要更多的内存资源,并且物理内存已经满了,此时,内存中那些不活跃的pages被移动(move) ...

  2. 做个地道的c++程序猿:copy and swap惯用法

    如果你对外语感兴趣,那肯定听过"idiom"这个词.牛津词典对于它的解释叫惯用语,再精简一些可以叫"成语".想要掌握一门语言,其中的"成语" ...

  3. swap分区扩展的三种方法

    redhat linux swap分区扩展的三种方法 2016-12-26 11:41:08 分类: LINUX 原文地址:redhat linux swap分区扩展的三种方法 作者:quanshen ...

  4. uva12545 Bits Equalizer

    uva12545 Bits Equalizer You are given two non-empty strings S and T of equal lengths. S contains the ...

  5. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  6. C++11智能指针

    今晚跟同学谈了一下智能指针,突然想要看一下C++11的智能指针的实现,因此下了这篇博文. 以下代码出自于VS2012 <memory> template<class _Ty> ...

  7. Codeforces Gym 100203E E - bits-Equalizer 贪心

    E - bits-EqualizerTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest ...

  8. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

  9. Linux内核入门到放弃-页面回收和页交换-《深入Linux内核架构》笔记

    概述 可换出页 只有少量几种页可以换出到交换区,对其他页来说,换出到块设备上与之对应的后备存储器即可,如下所述. 类别为 MAP_ANONYMOUS 的页,没有关联到文件,例如,这可能是进程的栈或是使 ...

随机推荐

  1. canvas 实现 github404动态效果

    使用canvas来完成github404的动态效果 前几天使用css样式和js致敬了一下github404的类似界面,同时最近又接触了canvas,本着瞎折腾的想法,便借着之前的js的算法,使用can ...

  2. JavaScript 中 append()、prepend()、after()、before() 的区别

    内容 append().prepend().after().before() 的区别 jQuery 操作 DOM 之添加节点 方法名 作用 $(selector).append() 指定元素内部添加, ...

  3. c++对c的拓展_using

    using 声明:使指定标识符可用   注意:与其他同名标识符有作用域冲突时产生二义性即报错 using 编辑指令: 使整个命名空间标识符可用 注意:与其他同名标识符作用域发生冲突使时优先使用局部变量 ...

  4. C++---条件结构和循环结构

    条件结构 if结构 #include <iostream> using namespace std; int main() { //判断用户输入的字符是否是合法的硬盘盘符A-Z char ...

  5. VUE(uni-app)+SSM 微信小程序

    环境 jdk:1.8.0_181 tomcat:7.0.100 mysql:8.0.25 工具 ideaIU+Hbuilder 遇到的问题 1.需要跳转到注册在tobar中页面时,需使用 uni.sw ...

  6. Linux shell中2>&1的含义解释

    https://blog.csdn.net/zhaominpro/article/details/82630528

  7. 这个API Hub厉害了,收录了钉钉企业微信等开放Api,还能直接调试

    01 此前时不时会有一些研发小伙伴和我诉苦,说很多企业由于人力财力限制或者需求不强,会直接购买使用第三方的开放API,这样一来, 一则由于开放项目不是量身定制的,寻找自己合适的接口也要搜索调研蛮多时间 ...

  8. JAVA语言学习day16--7月22日

    ###15用户选择功能 * A: 用户选择功能 * a: 案例代码 import java.util.ArrayList; import java.util.Scanner; /* * 超市管理系统主 ...

  9. node.js - 路由、中间件、mysql

    这几天天天搞到这么晚,我看今天的内容看起不多啊,不知道为什么学着学着就到了这么晚.今天的内容还是有点多哈,有点自我矛盾了,再次一一道来. 1. 首先今天先看到路由的概念,什么叫做路由? 路由就是映射关 ...

  10. 2021.12.06 平衡树——Treap

    2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...