很好的题呢

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. 在Android中区分点击和滑动操作

    转自:http://blog.csdn.net/do168/article/details/51587933 最近在写一个图片浏览安卓应用,想要弄成全屏显示,只在单击时显示工具栏和状态栏,在触摸滑动时 ...

  2. 浅谈Web前后端分离的意义

    自然是有很大意义的.下面我可能说的比较多--方便题主能够更全面的了解为什么说是有有意义的.另外,本文是以Java的角度谈前后端分离.放心,大家一定会有种是我了,没错,的感觉. 一.先来明晰下概念 前后 ...

  3. SVN 添加账号密码的方法(Windows 系统完整版)

    前言: 本人新接了一个项目,目前该项目基本完工,现在想要将该项目上传至SVN上保管,然后设置并添加账号密码信息,以便于后期加入这个项目的小伙伴可以通过新增加的账号密码信息获取到SVN项目,以便后期项目 ...

  4. Water 2.5.8 发布,一站式服务治理平台

    Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...

  5. SpringMVC的数据响应-回写数据

    1.直接返回字符串 其他具体代码请访问chilianjie @RequestMapping("/report5") public String save5(HttpServletR ...

  6. Spring-Bean依赖注入(引用数据类型和集合数据类型)

    为什么使用spring依赖注入详见–>依赖注入分析 1.创建实体类User类 package com.hao.domain; public class User { private String ...

  7. centos6的yum源更新版本

    概述 centos6系统从2020年12月1号开始不再维护,官方的yum源不再可用,同时国内的阿里云镜像和163镜像也都不再可用. 但是我们有一些老的服务器仍然在使用centos6系统版本,依赖库的安 ...

  8. intel 82599网卡(ixgbe系列)术语表

    Intel® 82599 10 GbE Controller Datasheet 15.0 Glossary and Acronyms 术语表 缩写 英文解释 中文解释 1 KB A value of ...

  9. linux磁盘之分区类型id

    我们通过命令来查看一下linux系统定义的分区类型id及其意义(更改磁盘分区类型必须掌握)系统采样: [root@fp-web-130 ~]# cat /etc/redhat-release Cent ...

  10. Hyperledger Fabric的test-network启动过程Bash源码详解

    前言 在基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简单案例中,我们已经完成了Fabric 2.4的环境搭建及fabric-samples/test-network官 ...