zoukankan      html  css  js  c++  java
  • 「SCOI2015」小凸玩密室

    题目描述

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

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

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

    数据范围

    $1 leq N leq 2 imes 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;
    }
  • 相关阅读:
    堆重启_uaf_hacknote
    记一次Spring表达式注入
    绕过waf的另类木马文件攻击方法
    西湖论剑 Flagshop 分析复现
    【测开基础之计算机网络】二: 物理层_网络_TesterAllen的博客CSDN博客
    测试面试 | 某 BAT 大厂测试开发面试真题与重点解析
    谁懂这篇文,玩游戏还会卡顿?
    移动自动化测试入门,你必须了解的背景知识和工具特性
    Python 自动化测试(三): pytest 参数化测试用例构建
    接口自动化测试分层设计与实践总结
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/11779154.html
Copyright © 2011-2022 走看看