bzoj 4446: [Scoi2015]小凸玩密室

时间:2022-01-12 00:44:24

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&period;4446&period;&lbrack;SCOI2015&rsqb;小凸玩密室&lpar;树形DP&rpar;

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

  2. bzoj 4446&colon; &lbrack;Scoi2015&rsqb;小凸玩密室【树形dp】

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

  3. &lbrack;BZOJ4446&rsqb;SCoi2015 小凸玩密室 树形DP&lpar;烧脑高能预警&rpar;

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

  4. BZOJ 4443&colon; &lbrack;Scoi2015&rsqb;小凸玩矩阵 最大流

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

  5. bzoj 4443 &lbrack;Scoi2015&rsqb;小凸玩矩阵 网络流&comma;二分

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

  6. BZOJ4446&colon;&lbrack;SCOI2015&rsqb;小凸玩密室&lpar;树形DP&rpar;

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

  7. BZOJ4446 &lbrack;Scoi2015&rsqb;小凸玩密室 【树形Dp】

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

  8. &lbrack;bzoj4446&rsqb; &lbrack;loj&num;2009&rsqb; &lbrack;Scoi2015&rsqb; 小凸玩密室

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

  9. 【刷题】BZOJ 4443 &lbrack;Scoi2015&rsqb;小凸玩矩阵

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

随机推荐

  1. Java反编译插件JadClipse

    Java反编译是很容易的,现在就介绍一个反编译插件,以后我们通过Ctrl+鼠标左键查看源码就容易得多了,不用再担心源码找不到了,配置过程很简单的. 准备: 1.下载JadClipse(jar文件,ec ...

  2. verilog实现的16位CPU单周期设计

    verilog实现的16位CPU单周期设计 这个工程完成了16位CPU的单周期设计,模块化设计,包含对于关键指令的仿真与设计,有包含必要的分析说明. 单周期CPU结构图 单周期CPU设计真值表与结构图 ...

  3. 【Python】入门 list有些不懂

    # -*- coding: utf-8 -*- # -*- coding: cp936 -*- 首行加这个 代码里就可以加注释 raw_input("Press Enter Exit&quo ...

  4. IIS6&period;0部署asp&period;net网站步骤图解

    IIS 发布步骤 1, 程序->运行->输入inetmgr,打开IIS管理器; 2, 展开左侧树形目录->右击“网站”->新建->网站,打开网站创建向导; 3, 点击“下 ...

  5. Jenkins 六: 构建中执行shell或者 windows的批处理程序

    Shell/ bat Jenkins 可以在构建中执行shell命令或者windows的batch 命令. 1. 选择一个项目,点击“配置”. 2. 找到“构建” –> “增加构建步骤”.选择 ...

  6. HttpApplication实战大文件上传 &lpar;第四篇&rpar;

    一.Asp.net中的文件上传 在Asp.net 1.1中,文件在上传过程中将被全部保存在内存中,对于大文件来说,会造成内存空间的过度使用,可能会招致恶意攻击.为了解决这个问题,Asp.net在配置文 ...

  7. Qt Creator插件工作流程代码走读

    Qt Creator有个很风骚的插件管理器PluginManager,还有个很骚包的插件说明PluginSpec.基本上,所有的Qt程序的入口都是传统的C程序一样,代码流程从main()函数开始.  ...

  8. 重要的几个热键&lbrack;Tab&rsqb;&comma; &lbrack;ctrl&rsqb;-c&comma; &lbrack;ctrl&rsqb;-d

    来源于:鸟哥的Linux私房菜 在继续后面的章节之前,这里很需要跟大家再来报告一件事,那就是我们的文字模式里头具有很多的功能按键, 这些按键可以辅助我们进行指令的编写与程序的中断呢!这几个按键请大家务 ...

  9. ext组件的查询方式

    1.使用id进行查询 (1)Ext.ComponentQuery.query("#mypanel") (2)Ext.getCmp("mypanel") 2.根据 ...

  10. Confluence 6 用户目录图例 - 使用 LDAP 授权,在用户第一次登陆时拷贝用户

    上面的图:Confluence 连接到一个 LDAP 目录只用作授权,当用户登录 Confluence 的时候,使用 LDAP 授权并且将用户信息同步到本地路服务器上. https://www.cwi ...