二分枚举答案,判定答案是否合法

贪心:每一个叶子只能经过一遍,因此叶子的顺序一定是一个dfs序,即走完一棵子树中的所有叶子才会到子树外

根据这个贪心可以dp,设$f[k][l][r]$表示仅考虑$k$的子树,$l$和$r$为第一个和最后一个叶子到根的距离,时间复杂度大约有$o(n^{4或5})$,无法通过

考虑优化,将所有$f[k][l][r]=1$的$(l,r)$记录下来,若存在$l'\le l$且$r'\le r$,$(l,r)$一定没有意义,这可以用一个单调栈来维护,那么同一个$l/r$所对应的$r/l$最多只有1个

转移考虑合并,不妨假设左子树比右子树小,枚举左子树中的$(l_{1},r_{1})$,对于右子树中的$(l_{2},r_{2})$,有两种转移的可能:1.若$r_{1}+l_{2}+v_{ls}+v_{rs}\le ans$,转移到$(l_{1}+v_{ls},r_{2}+v_{rs})$;2.若$l_{1}+r_{2}+v_{ls}+v_{rs}\le ans$,转移到$(l_{2}+v_{rs},r_{1}+v_{ls})$

可以利用单调性来优化,即找到满足$l_{2}\le ans-r_{1}-v_{ls}-v_{rs}$且$r_{2}$最小的位置(第一种转移),那么每一组$(l_{1},r_{1})$最多转移到$k$中的两个状态(反之同理),即有$|state[k]|\le 2\min(|state[ls]|,|state[rs]|)$,空间复杂度为$o(n\log_{2}n)$,时间复杂度即为空间复杂度乘上二分,为$o(n\log^{\ 2}_{2}n)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 #define fi first
6 #define se second
7 vector<pair<ll,ll> >v,f[N];
8 int n,x,ls[N],rs[N],w[N];
9 ll ans;
10 void dfs(int k){
11 f[k].clear();
12 if ((!ls[k])&&(!rs[k])){
13 f[k].push_back(make_pair(0,0));
14 return;
15 }
16 dfs(ls[k]);
17 dfs(rs[k]);
18 ll s=ans-w[ls[k]]-w[rs[k]];
19 for(int i=0,j=0;i<f[ls[k]].size();i++){
20 while ((j<f[rs[k]].size())&&(f[rs[k]][j].fi<=s-f[ls[k]][i].se))j++;
21 if ((j)&&(f[rs[k]][j-1].fi<=s-f[ls[k]][i].se))f[k].push_back(make_pair(f[ls[k]][i].fi+w[ls[k]],f[rs[k]][j-1].se+w[rs[k]]));
22 }
23 swap(ls[k],rs[k]);
24 for(int i=0,j=0;i<f[ls[k]].size();i++){
25 while ((j<f[rs[k]].size())&&(f[rs[k]][j].fi<=s-f[ls[k]][i].se))j++;
26 if ((j)&&(f[rs[k]][j-1].fi<=s-f[ls[k]][i].se))f[k].push_back(make_pair(f[ls[k]][i].fi+w[ls[k]],f[rs[k]][j-1].se+w[rs[k]]));
27 }
28 if (!f[k].size())return;
29 sort(f[k].begin(),f[k].end());
30 v.clear();
31 v.push_back(f[k][0]);
32 for(int i=1;i<f[k].size();i++)
33 if (f[k][i].se<v[(int)v.size()-1].se)v.push_back(f[k][i]);
34 f[k]=v;
35 }
36 bool pd(ll k){
37 ans=k;
38 dfs(1);
39 return f[1].size();
40 }
41 int main(){
42 scanf("%d",&n);
43 for(int i=2;i<=n;i++){
44 scanf("%d%d",&x,&w[i]);
45 if (!ls[x])ls[x]=i;
46 else rs[x]=i;
47 }
48 ll l=0,r=1LL*N*N;
49 while (l<r){
50 ll mid=(l+r>>1);
51 if (pd(mid))r=mid;
52 else l=mid+1;
53 }
54 printf("%lld",l);
55 }

[atAGC007E]Shik and Travel的更多相关文章

  1. 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]

    Shik and Travel Time Limit: 50 Sec  Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...

  2. AGC007E Shik and Travel 解题报告

    AGC007E Shik and Travel 题目大意:\(n\) 个点的二叉树,每个点要么两个儿子,要么没有儿子,每条边有边权. 你从 \(1\) 号节点出发,走到一个叶子节点.然后每一天,你可以 ...

  3. [AT2172] [agc007_e] Shik and Travel

    题目链接 AtCoder:https://agc007.contest.atcoder.jp/tasks/agc007_e 洛谷:https://www.luogu.org/problemnew/sh ...

  4. AtCoder Grand Contest 007 E:Shik and Travel

    题目传送门:https://agc007.contest.atcoder.jp/tasks/agc007_e 题目翻译 现在有一个二叉树,除了叶子每个结点都有两个儿子.这个二叉树一共有\(m\)个叶子 ...

  5. AT2172 Shik and Travel

    题目描述: luogu 题解: 二分+暴力$vector$+$dfs$. 记录下所有可能的子树内合法方案,双指针+归并合并. 代码: #include<vector> #include&l ...

  6. [AGC007E] Shik and Travel

    题目 给定一棵n节点的 以1为根的 满二叉树 (每个非叶子节点恰好有两个儿子)n−1 条边. 第ii条边连接 i+1号点 和 ai, 经过代价为vi设这棵树有m个叶子节点定义一次合法的旅行为:(1) ...

  7. AtCoder AGC007E Shik and Travel (二分、DP、启发式合并)

    题目链接 https://atcoder.jp/contests/agc007/tasks/agc007_e 题解 首先有个很朴素的想法是,二分答案\(mid\)后使用可行性DP, 设\(dp[u][ ...

  8. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

  9. AtCoder Grand Contest

    一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...

随机推荐

  1. 极简SpringBoot指南-Chapter01-如何用Spring框架声明Bean

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  2. bzoj4552排序(线段树,二分)

    题目大意 给定一个长度为n的序列,有m个操作,操作包括两种: \(0\ l\ r\)区间[l,r]的数字升序排序 \(1\ l\ r\)区间[l,r]的数字降序排序 最后询问在q位置上的数是多少? 其 ...

  3. Vue3学习(六)之使用Vue3进行数据绑定及显示列表数据

    一.写在前面 说来还是比较惭愧的,从周二开始事就比较多,周三还电脑坏了,然后修电脑等等一些杂事,忙的团团转,因为周二.周三自己走的过多了,导致不敢直腰,周四卧床一天. 之前都听说<陈情令> ...

  4. 占位符,SQL注入?

    这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说:Connection和PreparedStatement都没关.他说不止这方面的问题,还有sql注入的问题,我就坚决的说使用了占 ...

  5. DP接口中AUX

    背景技术: DP接口(DisplayPort)是一种图像显示接口,它不仅可以支持全高清显示分辨率(1920×1080),还能支持4k分辨率(3840×2160),以及最新的8k分辨率(7680×432 ...

  6. Python爬虫之爬取淘女郎照片示例详解

    这篇文章主要介绍了Python爬虫之爬取淘女郎照片示例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 本篇目标 抓取淘宝MM ...

  7. 最短路径算法:弗洛伊德(Floyd-Warshall)算法

    一.算法介绍 Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存 ...

  8. T-SQL——函数——时间操作函数

    目录 0. 日期和时间类型 0.0 时间类型 1. 转换函数 1.1 CAST 1.2 CONVERT 2. 日期操作函数 2.0 GETDATE和GETUTCDATE 2.1 SYSDATETIME ...

  9. 字典树(Trie)

    终于学会字典树了,真开心(然后就滚过来写总结了). 首先,字典树到底是个什么东西呢?请看下面这段话: 字典树,常被用来保存与查找大量的字符串,它利用了字符串之间的公共前缀来节约时间,但它的空间花费较大 ...

  10. 痞子衡嵌入式:借助Serial Plot软件测量i.MXRT系列FlexSPI驱动Flash页编程执行时间

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT系列FlexSPI驱动Flash页编程执行时间. 痞子衡之前写过一篇文章 <串行NOR Flash的页编程模式对于量产 ...