Solution -「JOISC 2019」「LOJ #3036」指定城市
\(\mathcal{Description}\)
Link.
给定一棵含 \(n\) 个结点的树,双向边权不相同。\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋向于某个标记点的有向边权值之和,求价值的最大值。
\(q\le n\le2\times10^5\)。
\(\mathcal{Solution}\)
\(e=1\text{ or }2\) 的时候可以直接换根求解。需要强调的是,当确定一个被标记的根时,其余标记点的贡献为根到这个标记点的有向路径长度(取并)。接下来引入一些结论。首先有:
对于一棵根被钦定标记的树(\(e=1\)),当 \(e=k<n\) 时,一定能通过标记深度最深的结点使得其成为 \(e=k\) 时的最优解。
不难意会。(
由此可以推出一个关键的结论:
对于 \(k>2\),\(e=k\) 时的最优解必然通过在某个 \(e=k-1\) 时的最优解的基础上新标记一个点得到。
记 \(e=k\) 时某个最优解标记点集合为 \(S\),\(e=k+1\) 时任一最优解的标记点集合为 \(T\),考虑反证,若不存在 \(S\sub T\):
- 若 \(S\cap T\neq\varnothing\),取一个 \(r\in S\cap T\),标记并作为树根。由上一个结论,矛盾。
- 若 \(S\cap T=\varnothing\),考虑把 \(T\) 中的一个结点丢到 \(S\) 中,此时 \(S\) 不会比 \(T\) 劣。
所以,以 \(e=2\) 时的一个标记点为根,令每片叶子的权值为其保持作为子树最深点,向上能爬的距离。排序取前 \(k\) 大之和加上一些常数就是 \(e=k\) 的答案。复杂度 \(\mathcal O(n\log n)\)。
\(\mathcal{Code}\)
/* Clearink */
#include <cstdio>
#include <algorithm>
#define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
typedef long long LL;
typedef std::pair<int, LL> PIL;
inline int rint() {
int x = 0, s = getchar();
for ( ; s < '0' || '9' < s; s = getchar() );
for ( ; '0' <= s && s <= '9'; s = getchar() ) x = x * 10 + ( s ^ '0' );
return x;
}
template<typename Tp>
inline void wint( Tp x ) {
if ( x < 0 ) putchar( '-' ), x = -x;
if ( 9 < x ) wint( x / 10 );
putchar( x % 10 ^ '0' );
}
inline LL lmax( const LL a, const LL b ) { return a < b ? b : a; }
inline void chkmax( LL& a, const LL b ) { a < b && ( a = b, 0 ); }
const int MAXN = 2e5;
const LL LINF = 1ll << 60;
int n, ecnt = 1, head[MAXN + 5], rt;
LL all, upsum, wgt[MAXN + 5];
struct Edge { int to, val, nxt; } graph[MAXN * 2 + 5];
inline void link( const int s, const int t, const int w ) {
graph[++ecnt] = { t, w, head[s] };
head[s] = ecnt;
}
namespace Subtask23 {
int siz[MAXN + 5], root;
LL sum[MAXN + 5], mx[MAXN + 5], sm[MAXN + 5], ans[2];
inline void init( const int u, const int fa ) {
siz[u] = 1, mx[u] = 0, sm[u] = -LINF;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
init( v, u );
siz[u] += siz[v], sum[u] += sum[v] + graph[i ^ 1].val;
LL d = mx[v] + graph[i].val;
if ( mx[u] < d ) sm[u] = mx[u], mx[u] = d;
else if ( sm[u] < d ) sm[u] = d;
}
}
}
inline void solve( const int u, const int fa, const LL ups, const LL upx ) {
chkmax( ans[0], sum[u] + ups );
LL tmp = sum[u] + ups + lmax( upx, mx[u] );
if ( ans[1] < tmp ) root = u, ans[1] = tmp;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
int w1 = graph[i].val, w2 = graph[i ^ 1].val;
LL ns = ups + sum[u] - sum[v] - w2 + w1;
LL nx = lmax( upx, mx[v] + w1 < mx[u] ? mx[u] : sm[u] ) + w2;
solve( v, u, ns, nx );
}
}
}
inline void main() {
init( 1, 0 );
solve( 1, 0, 0, 0 );
}
} // namespace Subtask23.
inline PIL init( const int u, const int fa ) {
PIL ret( u, 0 );
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
PIL tmp( init( v, u ) );
upsum += graph[i ^ 1].val;
wgt[tmp.first] += graph[i].val;
if ( tmp.second + graph[i].val > ret.second ) {
ret = { tmp.first, tmp.second + graph[i].val };
}
}
}
return ret;
}
int main() {
freopen( "city.in", "r", stdin );
freopen( "city.out", "w", stdout );
n = rint();
rep ( i, 2, n ) {
int u = rint(), v = rint(), a = rint(), b = rint();
all += a + b;
link( u, v, a ), link( v, u, b );
}
Subtask23::main();
rt = Subtask23::root;
init( rt, 0 );
// printf( "root is %d: ", rt );
// rep( i, 1, n ) printf( "%lld ", wgt[i] );
// puts( "" );
std::sort( wgt + 1, wgt + n + 1, []( const LL a, const LL b ) {
return a > b;
} );
rep( i, 1, n ) wgt[i] += wgt[i - 1];
for ( int q = rint(), e; q--; ) {
e = rint();
wint( all - ( e < 2 ? Subtask23::ans[0] :
upsum + wgt[e - 1] ) ), putchar( '\n' );
}
return 0;
}
Solution -「JOISC 2019」「LOJ #3036」指定城市的更多相关文章
- 【LOJ】#3036. 「JOISC 2019 Day3」指定城市
LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...
- 【LOJ】#3034. 「JOISC 2019 Day2」两道料理
LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...
- 【LOJ】#3032. 「JOISC 2019 Day1」馕
LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...
- 【LOJ】#3033. 「JOISC 2019 Day2」两个天线
LOJ#3033. 「JOISC 2019 Day2」两个天线 用后面的天线更新前面的天线,线段树上存历史版本的最大值 也就是线段树需要维护历史版本的最大值,后面的天线的标记中最大的那个和最小的那个, ...
- 【LOJ】#3031. 「JOISC 2019 Day1」聚会
LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...
- 【LOJ】#3030. 「JOISC 2019 Day1」考试
LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...
- 「JOISC 2019 Day3」穿越时空 Bitaro
「JOISC 2019 Day3」穿越时空 Bitaro 题解: 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. 问题变成二维平面上 ...
- @loj - 3039@ 「JOISC 2019 Day4」蛋糕拼接 3
目录 @description@ @solution@ @accepted code@ @details@ @description@ 今天是 IOI 酱的生日,所以她的哥哥 JOI 君给她预定了一个 ...
- 「JOISC 2019 Day4」蛋糕拼接 3
loj 3039 NKOJ Description \(n\)个蛋糕,每个蛋糕有\(w_i,h_i\).选\(m\)个蛋糕满足\(\sum\limits_{j=1}^mw_{k_j}-\sum\lim ...
随机推荐
- 虚拟机上CentOS7环境配置
原文链接:https://www.toutiao.com/i6493449649939022350/ 之前网络和基本环境以及完成,现在我们再配置一些内容,方便我们之后的学习. 设置网络YUM源 下载我 ...
- jsencrypt vue相关的rsa加密
vue组件引入 import { JSEncrypt } from 'jsencrypt' 方法内使用 let publicKey = asdfsafdadfafasjdhfasfd // 从后台获取 ...
- idea 个人settings和好看的主题推荐
idea 个人settings和好看的主题推荐 配置和主体搭配使用,效果最佳!!! 配置文件: 链接:https://pan.baidu.com/s/1K-oW9UNxUz_5XWz4Ru3_3w ...
- netty系列之:好马配好鞍,为channel选择配套的selector
目录 简介 netty服务的基本构建方式 EventLoopGroup channel 多种构建方式 其他的channel 总结 简介 我们知道netty的基础是channel和在channel之上的 ...
- Java学习小总结
本学期主要学习Java程序语言及Javaweb相关知识,其中有相当一部分内容是暑假假期的学习内容,以下主要介绍一些Javaweb学习的总结. 以下教程均为个人建议(当然,适合自己的最好) 一.环境配置 ...
- jdbc连接mysql数据库注意事项
1.导入mysql驱动 http://blog.csdn.net/a153375250/article/details/50851049 2.开放机器访问权限 mysql>GRANT ALL ...
- 数据库查询语句遇到:Unknown column 'XXXX' in 'where clause'解决方法
数据库查询语句遇到:Unknown colunm 'XXX' in 'where clause'解决方法 根本原因:可能是sql语句所用到的数据类型错误(int与String)弄错- 我的情况: 在网 ...
- 获取nginx日志状态码百分比脚本
#!/bin/bash pwd=/app/nginx/logs/access.log for num1 in `cat $pwd | awk '{print $9}' | grep -Ei " ...
- HTML Entry 源码分析
简介 从 HTML Entry 的诞生原因 -> 原理简述 -> 实际应用 -> 源码分析,带你全方位刨析 HTML Entry 框架. 序言 HTML Entry 这个词大家可能比 ...
- AT2163 [AGC006B] Median Pyramid Easy
需要一点灵感的题目. 可以发现这样一个事情,当三个数中有两个数相同时,中为数一定是这两个相同的数. 基于这个观察,我们想让每一行都存在这样两个相同的两个数,就一定能保证第一层的值为 \(x\) 了. ...