「SCOI2015」小凸玩密室

题目描述

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

点亮第 $1$ 个灯泡不需要花费,之后每点亮一个新的灯泡 $V$ 的花费,等于上一个被点亮的灯泡 $U$ 到这个点 $V$ 的距离 $D(u, v)$,乘以这个点的权值 $A_v$。

在点灯的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡。请告诉他们,逃出密室的最少花费是多少。

数据范围

$1 \leq N \leq 2 \times 10 ^ 5, 1 < A_i, B_i \leq 10 ^ 5$

题解

考虑暴力, $f_{i,j}$ 表示走完 $i$ 子树,直接走到 $j$ 的最小花费,转移考虑用左右儿子转移。

可以发现我们只需要知道 $j$ 为 $i$ 的祖先或者祖先的另一个儿子的 $f$ 值即可,于是复杂度降至 $nlogn$ 。

注意 $i$ 为叶子或者 $i$ 只有左儿子的情况。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+5;
int n;LL a[N],b[N],f[N][20],g[N][20],ans=2e18;
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for (int i=2;i<=n;i++)
        scanf("%lld",&b[i]),b[i]+=b[i>>1];
    for (int i=n,l,r;i;i--){
        l=i<<1;r=l|1;
        for (int j=i,x,y=1;j>1;j>>=1,y++){
            x=j^1;
            if (l>n) f[i][y]=a[x]*(b[i]+b[x]-(b[j>>1]<<1));
            else if (r>n) f[i][y]=f[l][y+1]+a[l]*(b[l]-b[i]);
            else f[i][y]=min(a[l]*(b[l]-b[i])+f[l][1]+f[r][y+1],
                            a[r]*(b[r]-b[i])+f[r][1]+f[l][y+1]);
        }
    }
    for (int i=n,l,r;i;i--){
        l=i<<1;r=l|1;
        for (int j=i>>1,y=1;;j>>=1,y++){
            if (l>n) g[i][y]=a[j]*(b[i]-b[j]);
            else if (r>n) g[i][y]=g[l][y+1]+a[l]*(b[l]-b[i]);
            else g[i][y]=min(a[l]*(b[l]-b[i])+f[l][1]+g[r][y+1],
                            a[r]*(b[r]-b[i])+f[r][1]+g[l][y+1]);
            if (!j) break;
        }
    }
    for (int j,x,i=1;i<=n;i++){
        LL v=g[i][1];j=i>>1;x=i^1;
        while(j){
            if (x>n) v+=a[j>>1]*(b[j]-b[j>>1]);
            else v+=a[x]*(b[x]-b[j])+g[x][2];
            x=j^1;j>>=1;
        }
        ans=min(ans,v);
    }
    return cout<<ans<<endl,0;
}

原文地址:https://www.cnblogs.com/xjqxjq/p/11779154.html

时间: 2024-10-09 10:10:50

「SCOI2015」小凸玩密室的相关文章

LibreOJ #2009. 「SCOI2015」小凸玩密室

二次联通门 : LibreOJ #2009. 「SCOI2015」小凸玩密室 /* LibreOJ #2009. 「SCOI2015」小凸玩密室 树形dp 做到这么正常的题突然感觉好不适应.... 考虑转移 f[x][y] 表示从x点转移到y点的代价 则我们需要处理出以x为根的子树的代价 讨论处理一下即可(有没有左儿子,有没有右儿子,或是都有) 但是这样转移是O(N^2)的 所以我们考虑优化 显然有很多转移是不需要的 比如y在x的子树中时就没必要转移 那么考虑优化 设g[x][i]表示走完x的子

—Libre#2009. 「SCOI2015」小凸玩密室

#2009. 「SCOI2015」小凸玩密室 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方相约玩密室逃脱,这个密室是一棵有 n nn 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 Ai A_iA?i??,每条边也有个权值 bi b_ib?i??. 点亮第 1 11 个灯泡不需要花费,之后每点亮一个新的灯泡 V VV 的花费,等于上一个被点亮的

LibreOJ #2006. 「SCOI2015」小凸玩矩阵

二次联通门 : LibreOJ #2006. 「SCOI2015」小凸玩矩阵 /* LibreOJ #2006. 「SCOI2015」小凸玩矩阵 本来以为是道数据结构题 后来想了想发现不可做 就考虑二分dp判断 推方程推不出来 就考虑用网络流判断了 二分出一个数 将小于这个数的位置的点编号 每行的可行点与下一行可行的点连边 后一边最大流判断可选出的数的个数是否符合要求即可 */ #include <cstdio> #include <iostream> #include <q

LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 N NN 个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的 N NN 个数中第 K KK 大的数字的最小值是多少. 输入格式 第一行给出三个整数

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

4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 个(1个)新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av.在点灯 的过程中,要保证任意时刻所有被点亮的灯泡必须连

bzoj4446[Scoi2015]小凸玩密室

4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 419  Solved: 173[Submit][Status][Discuss] Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 个新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的

小凸玩密室题解

小凸玩密室题解 恶心题啊-- 开始连题意都看不懂, 看了会题解的题意简化,结果理解错了题意,说多了都是泪啊- 首先说说题意吧: 点亮一盏灯后,只有点亮完子树内所有灯后才能点其他灯,而且点亮的灯要求要连通. -->下一步一定点两个儿子之一,先点完这个儿子的子树再点另一个儿子. 然而,上一盏灯点什么十分不好求,贡献算不出(一个点子树内有多个层数相同的子孙). 但是,我们可以通过上一盏灯算下一盏灯的贡献啊(每个点只有一个层数一定的父辈). 所以点完这个点后,我们只有两种情况: 1.我们点完这个点后构成

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

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

[Scoi2015]小凸玩矩阵

bzoj 4443: [Scoi2015]小凸玩矩阵 http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N