[atAGC007E]Shik and Travel
二分枚举答案,判定答案是否合法
贪心:每一个叶子只能经过一遍,因此叶子的顺序一定是一个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的更多相关文章
- 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]
		
Shik and Travel Time Limit: 50 Sec Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...
 - AGC007E Shik and Travel 解题报告
		
AGC007E Shik and Travel 题目大意:\(n\) 个点的二叉树,每个点要么两个儿子,要么没有儿子,每条边有边权. 你从 \(1\) 号节点出发,走到一个叶子节点.然后每一天,你可以 ...
 - [AT2172] [agc007_e] Shik and Travel
		
题目链接 AtCoder:https://agc007.contest.atcoder.jp/tasks/agc007_e 洛谷:https://www.luogu.org/problemnew/sh ...
 - AtCoder Grand Contest 007 E:Shik and Travel
		
题目传送门:https://agc007.contest.atcoder.jp/tasks/agc007_e 题目翻译 现在有一个二叉树,除了叶子每个结点都有两个儿子.这个二叉树一共有\(m\)个叶子 ...
 - AT2172 Shik and Travel
		
题目描述: luogu 题解: 二分+暴力$vector$+$dfs$. 记录下所有可能的子树内合法方案,双指针+归并合并. 代码: #include<vector> #include&l ...
 - [AGC007E] Shik and Travel
		
题目 给定一棵n节点的 以1为根的 满二叉树 (每个非叶子节点恰好有两个儿子)n−1 条边. 第ii条边连接 i+1号点 和 ai, 经过代价为vi设这棵树有m个叶子节点定义一次合法的旅行为:(1) ...
 - AtCoder AGC007E Shik and Travel (二分、DP、启发式合并)
		
题目链接 https://atcoder.jp/contests/agc007/tasks/agc007_e 题解 首先有个很朴素的想法是,二分答案\(mid\)后使用可行性DP, 设\(dp[u][ ...
 - AtCoder Grand Contest 007
		
AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...
 - AtCoder Grand Contest
		
一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...
 
随机推荐
- sarama的消费者组分析、使用
			
以前老的sarama版本不支持消费者组的消费方式,所以大多数人都用sarama-cluster. 后来sarama支持了消费者组的消费方式,sarama-cluster也停止维护了,但网上关于sara ...
 - SQL 居然还能在 Apache ShardingSphere 上实现这些功能?
			
在去年 10 月 5.0.0-alpha 版本发布之后,Apache ShardingSphere 经历了长达 8 个多月的持续开发与优化,终于在 6 月 25 日正式迎来了 5.0.0-beta 版 ...
 - 洛谷4755 Beautiful Pair (分治)
			
题目描述 小D有个数列 \(a\),当一个数对 \((i,j)(i\le j)\) 满足\(a_i\)和\(a_j\)的积 不大于 \(a_i \cdots a_j\) 中的最大值时,小D认为这个数对 ...
 - Python - faker
			
安装 faker pip install Faker pip install Dumper 设置生成器 from faker import Faker fake = Faker() 它可以通过访问以想 ...
 - silky微服务快速开始
			
项目介绍 Silky框架旨在帮助开发者在.net平台下,通过简单代码和配置快速构建一个微服务开发框架. Silky 通过 .net core的主机来托管微服务应用.通过 Asp.Net Core 提供 ...
 - Java/JDK/J2SE
			
Java8与JDK1.8与JDK8与J2SE8与J2SE1.8的区别是什么? Java是面向对象的编程语言,在我们开发Java应用的程序员的专业术语里,Java这个单词其实指的是Java开发工具,也就 ...
 - 如何再一台电脑上配置多个tomcat同时运行
			
1.配置运行tomcat 首先要配置java的jdk环境,这个就不在谢了 不懂去网上查查,这里主要介绍再jdk环境没配置好的情况下 如何配置运行多个tomcat 2.第一个tomcat: 找到&qu ...
 - 通过Nacos动态刷新Spring Cloud Gateway的路由
			
通过Nacos动态刷新Spring Cloud Gateway的路由 一.背景 二.解决方案 三.实现功能 四.实现步骤 1.网关服务的实现 1.pom文件 2.bootstrap.yml配置文件 3 ...
 - 线路由器频段带宽是是20M好还是40M好
			
无线路由器频段带宽还是40M好. 40M的信号强,速度快. 1.20MHz在11n的情况下能达到144Mbps带宽.穿透性不错.传输距离较远 40MHz在11n的情况下能达到300Mbps带宽.穿 ...
 - Django(72)Django认证系统库--djoser
			
djoser是什么? 作用:Django认证系统的REST实现.djoser库提供了一组Django Rest Framework视图,用于处理注册.登录.注销.密码重置和帐户激活等基本操作.它适 ...