Description

小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡。点亮所有灯
泡即可逃出密室。每个灯泡有个权值Ai,每条边也有个权值bi。点亮第1个灯泡不需要花费,之后每点亮4
个新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av。在点灯
的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡。请告诉他们,逃出密室的最少花费是多少。

Input

第1行包含1个数n,代表节点的个数
第2行包含n个数,代表每个节点的权值ai。(i=l,2,…,n)
第3行包含n-l个数,代表每条边的权值bi,第i号边是由第(i+1)/2号点连向第i+l号点的边。
(i=l,2...N-1)

Output

输出包含1个数,代表最少的花费。

Sample Input

3
5 1 2
2 1

Sample Output

5

HINT

对于100%的数据,1≤N≤2×105,1<Ai,Bi≤10^5

Source

dp神题,逆推所需,水到渠成;

题目给了很多信息:
1.完全二叉树,那么树高为log,且每个点最多两个儿子;

2.点亮的灯时刻是一个连通块,且必须点亮完其子树内的点才能点亮其他点;

因为第一个点是不确定的,所以我们可以尝试枚举第一个点x,然后开始点灯,因为需要满足点亮的灯时刻是一个连通块并且一定要处理完子树内才能往外走,所以点灯的顺序一定是:

x的子树->x的父亲->x的兄弟的子树->x的爸爸的爸爸...这样一直搞直到根为止;

这个时候我们就会需要一个知道一个g[x][y],表示处理完x的子树后,走到了y节点的代价(其中y为x的祖先),因为树高为log,所以第二维开一个log就可以了,表示深度为y的祖先;

我们考虑如何求g[x][y],如果x是叶子节点,那么直接走过去就好了;

否则的话就有两个选择,先走左子树还是先走右子树,如果是先走左子树的话,点完左子树后,我们需要去点亮x的右儿子,然后把右子树点完,然后从右子树中某点去点x的深度为y的祖先;

这个时候我们还需要求出处理完x的子树后,走到了x的兄弟的代价,这个我们用一个数组f[x][y],表示处理完x的子树后,走到了x的深度为y的兄弟的代价;

因为为完全二叉树,那么x的k级父亲可以直接用位运算算出来,g[x][y]和f[x][y]都能通过合并左右两子树的信息来得到;

最后我们枚举每个点用g数组来模拟覆盖的过程即可;

注意叶子节点和没有右儿子的节点特殊处理一下;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=200050;
ll g[N][20],f[N][20],a[N],b[N],n,dep[N],dis[N];
int main(){
scanf("%lld",&n);dep[1]=1;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=2;i<=n;i++){
scanf("%lld",&b[i]);
dep[i]=dep[i>>1]+1;dis[i]=dis[i>>1]+b[i];
}
for(int x=n;x;x--){
if((x<<1)>n){
for(int j=0;j<=dep[x];j++){
int fa=(x>>(dep[x]-j+1)),y=((x>>(dep[x]-j))^1);
f[x][j]=(dis[x]+dis[y]-2*dis[fa])*a[y];
}
}
else if((x<<1)==n){
for(int j=0;j<=dep[x];j++){
int y=(x<<1);
f[x][j]=a[y]*b[y]+f[y][j];
}
}
else {
for(int j=0;j<=dep[x];j++){
int lson=(x<<1),rson=(x<<1|1);
f[x][j]=min(a[lson]*b[lson]+f[lson][dep[lson]]+f[rson][j],a[rson]*b[rson]+f[rson][dep[rson]]+f[lson][j]);
}
}
}
for(int x=n;x;x--){
if((x<<1)>n){
for(int j=0;j<=dep[x];j++){
int y=(x>>(dep[x]-j));
g[x][j]=(dis[x]-dis[y])*a[y];
}
}
else if((x<<1)==n){
for(int j=1;j<=dep[x];j++){
int y=(x<<1);
g[x][j]=a[y]*b[y]+g[y][j];
}
}
else{
for(int j=0;j<=dep[x];j++){
int lson=(x<<1),rson=(x<<1|1);
g[x][j]=min(a[lson]*b[lson]+f[lson][dep[lson]]+g[rson][j],a[rson]*b[rson]+f[rson][dep[rson]]+g[lson][j]);
}
}
}
ll ans=g[1][0];
for(int i=2;i<=n;i++){
ll ret=g[i][dep[i]-1];
for(int x=i;x>1;x>>=1){
int y=x^1;
if(y>n) ret+=a[x>>2]*b[x>>1];
else ret+=a[y]*b[y]+g[y][dep[y]-2];
}
ans=min(ans,ret);
}
printf("%lld\n",ans);
return 0;
}

bzoj 4446: [Scoi2015]小凸玩密室的更多相关文章

  1. BZOJ.4446.[SCOI2015]小凸玩密室(树形DP)

    BZOJ LOJ 洛谷 (下面点亮一个灯泡就说成染色了,感觉染色比较顺口... 注意完全二叉树\(\neq\)满二叉树,点亮第一个灯泡\(\neq\)第一次点亮一号灯泡,根节点应该就是\(1\)... ...

  2. bzoj 4446: [Scoi2015]小凸玩密室【树形dp】

    神仙题!参考https://www.cnblogs.com/wfj2048/p/7695711.html 注意完全二叉树不是满二叉树!!!! 设g[u][j]为u遍历完子树到深度为i-1的祖先的兄弟的 ...

  3. [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)

    4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...

  4. BZOJ 4443: [Scoi2015]小凸玩矩阵 最大流

    4443: [Scoi2015]小凸玩矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Description 小凸和小方是好 ...

  5. bzoj 4443 [Scoi2015]小凸玩矩阵 网络流,二分

    [Scoi2015]小凸玩矩阵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1564  Solved: 734[Submit][Status][Di ...

  6. BZOJ4446:[SCOI2015]小凸玩密室(树形DP)

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室. 每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...

  7. BZOJ4446 [Scoi2015]小凸玩密室 【树形Dp】

    题目 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 ...

  8. [bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \ ...

  9. 【刷题】BZOJ 4443 [Scoi2015]小凸玩矩阵

    Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最 ...

随机推荐

  1. 用TensorFlow实现文本分析模型,做个聊天机器人

    用TensorFlow实现文本分析模型,做个聊天机器人 聊天机器人的架构简图用 TensorFlow 实现 Chatbot 的模型如何准备 chatbot 的训练数据Chatbot 源码解读 1. 聊 ...

  2. c语言贪吃蛇详解-2.画出蛇

    c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...

  3. 35.Linux-分析并制作环形缓冲区

    在上章34.Linux-printk分析.使用printk调试驱动里讲述了: printk()会将打印信息存在内核的环形缓冲区log_buf[]里, 可以通过dmesg命令来查看log_buf[] 1 ...

  4. NTP时间同步 服务端 客户端 自动化安装配置

    NTP时间同步 服务端 客户端 自动化安装配置 原创内容 http://www.cnblogs.com/elvi/p/7657994.html #!/bin/sh #运行环境 centos6.cent ...

  5. 利用阿里云Centos7建站过程

    以下可能不尽详述,如有问题欢迎指出 准备过程:1. 阿里云主机一台2.域名一个 3.github个人帐号开始: 1.以root帐号登录云主机 2.安装apache [root@192 ~]# yum ...

  6. Python 串口通信操作

    下载  pyserial包 https://pypi.python.org/packages/source/p/pyserial/pyserial-2.7.tar.gz#md5=794506184df ...

  7. nefu 115 循环节

    斐波那契的整除 Problem:115 Time Limit:1000ms Memory Limit:65536K Description 已知斐波那契数列有如下递归定义,f(1)=1,f(2)=1, ...

  8. 天天乐宝APP开发

    "互联网+"时代是一个"信息过剩"的时代,也是一个"注意力稀缺"的时代,怎样在"无限的信息中"获取"有限的注意 ...

  9. MySQL数据库数据信息迁移

    环境内核信息: [root@zabbix-01 ~]# uname -a Linux lodboyedu-01 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:2 ...

  10. 工作中git 操作汇总

    1. git branch -l  查看本地branch 2. git reset --hard 回滚全部修改 3. git status  查看本地修改 4. git pull 更新代码 5. gi ...