很好的题呢

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. CSS的inline、block与inline-block

    基本知识点 行内元素一般是内容的容器,而块级元素一般是其他容器的容器,行内元素适合显示具体内容,而块级元素适合做布局. 块级元素(block):独占一行,对宽高的属性值生效:如果不给宽度,块级元素就默 ...

  2. Html5 Canvas学习之路(五)

    Canvas 图像(上) Canvas 图像API可以加载图像数据,然后直接将图像应用到画布上.还可以裁切.拼贴图像数据,以显示用户需要的部分.此外,Canvas还提供了像素数据的存储功能,这样就能对 ...

  3. javaweb之删除功能

    对数据库的删除,主要是通过表中的一个数据查询来进行逐个删除,否则会清空整张表. 一.dao层 在dao层加入删除方法 public boolean delete(Course n) { boolean ...

  4. java的命令行参数到底怎么用,请给截图和实际的例子

    8.2 命令行参数示例(实验) public class Test {    public static void main(String[] args){        if(args.length ...

  5. Spring集成web环境(使用封装好的工具)

    接上文spring集成web环境(手动实现) ##########代码接上文############# spring提供了一个监听器ContextLoaderListener对上述功能的封装,该监听器 ...

  6. .Net Core 进程守护之Supervisor使用

    1.执行下列命令安装supervisor wget https://mirrors.tuna.tsinghua.edu.cn/epel/epel-release-latest-7.noarch.rpm ...

  7. Linux下编写和加载 .ko 文件(编写linux驱动)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...

  8. HTTP请求头格式和响应格式

    HTTP请求头格式 提示: 回车符 \r 换行符 \n 请求首行分析: 请求方式: GET 和 POST 方式: GET请求:地址栏访问.超链接访问都是get请求方式,get请求方式不安全,地址栏大小 ...

  9. JS/JQ动态创建(添加)optgroup和option属性

    JavaScript和Jquery动态操作select下拉框 相信在前端设计中必然不会少的了表单,因为经常会使用到下拉框选项,又或是把数据动态回显到下拉框中.因为之前牵扯到optgroup标签时遇到了 ...

  10. Python技能树及CSDN MarkDown编辑器测评

    测评目录 python技能树测评 python技能树是什么 python技能树长什么样 如何学习python技能树 python技能树可能需要的改进 对python技能树的总结 CSDN MarkDo ...