\(\mathcal{Description}\)

  OurTeam.

  给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和。树形生成方式为随机取不连通两点连边直到全部连通。

  \(n\le32000\)。

\(\mathcal{Solution}\)

  考虑用中位数的标准姿势统计每条边的贡献——小于它的设为 \(-1\),大于它的设为 \(+1\),边权相等按编钦定大小关系。那么这条边的贡献就是路径两端权值加和为 \(0\) 的路径对数(显然每对路径连起来都是奇数路径)。

  令 \(f(u,i)\) 表示 \(u\) 子树内到 \(u\) 路径权值和为 \(i\) 的结点数量。对于一条边 \((u,v)\),不妨设 \(u\) 是 \(v\) 的父亲,设我们已经得到了全树的 DP 信息,考虑到题目中随机树的期望深度为 \(\mathcal O(\sqrt n)\),所以暴力爬树统计 \(v\) 子树内和 \(v\) 子树外的信息即可求到当前答案。顺序枚举边,每条边仅会由 \(+1\) 变为 \(-1\),所以暴力仍然暴力爬树修改 DP 信息即可。实现上,利用树深限制,拿一个内存池储存 DP 信息;爬树统计时限制可能贡献答案的权值区间即可通过本题。

  复杂度 \(\mathcal O(n^2)\),不过可以算出带一个 \(\frac{1}6\) 的常数,所以可过。

\(\mathcal{Code}\)

  这里以直径中点作为根(为了和某毒瘤比赛卡常),不过随便选一个根都是可过的。

#include <queue>
#include <cstdio>
#include <cstring> typedef long long LL; const int MAXN = 32000, MAXSQRT = 180, MAXV = 1e6;
int n, ecnt, head[MAXN + 5], fa[MAXN + 5], dep[MAXN + 5], faw[MAXN + 5];
int mempool[MAXN * MAXSQRT * 2], *f[MAXN + 5], *frepos = mempool, *g;
int pre[MAXN + 5], buc[MAXV + 5], ori[MAXN + 5], down[MAXN + 5]; struct Edge { int to, cst, nxt; } graph[MAXN * 2 + 5];
struct EdgeSet { int u, v, w; } eset[MAXN + 5]; inline int rint () {
int x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} inline int min_ ( const int a, const int b ) { return a < b ? a : b; }
inline int max_ ( const int a, const int b ) { return a < b ? b : a; } inline void link ( const int s, const int t, const int c ) {
graph[++ ecnt] = { t, c, head[s] };
head[s] = ecnt;
} inline void BFS ( const int s ) {
static std::queue<int> que;
que.push ( s ); dep[s] = 1;
while ( ! que.empty () ) {
int u = que.front (); que.pop ();
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ! dep[v = graph[i].to] ) {
pre[v] = u, dep[v] = dep[u] + 1;
que.push ( v );
}
}
}
} inline void init ( const int u ) {
dep[u] = 0;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa[u] ) {
fa[v] = u, faw[v] = 1, down[graph[i].cst] = v, init ( v );
if ( dep[v] + 1 > dep[u] ) dep[u] = dep[v] + 1;
}
}
f[u] = frepos += dep[u] + 1, frepos += dep[u] + 1;
} inline void DP ( const int u ) {
*f[u] = 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa[u] ) {
DP ( v );
for ( int j = -dep[v]; j <= dep[v]; ++ j ) f[u][j + 1] += f[v][j];
}
}
} inline LL update ( const int s ) {
int l = -dep[s], r = dep[s]; faw[s] = -1;
for ( int u = fa[s], v = s, d1 = 0, d2 = 0; u; u = fa[v = u] ) {
d1 += v ^ s ? faw[v] : 1, d2 += faw[v];
for ( int i = -dep[s]; i <= dep[s]; ++ i ) {
f[u][i + d1] -= f[s][i];
f[u][i + d2] += f[s][i];
}
for ( int i = max_ ( -dep[u], l ), t = min_ ( dep[u], r ), d = d2 + 1; i <= t; ++ i ) {
g[i + d] += f[u][i] - f[v][i - faw[v]];
}
l -= faw[u], r -= faw[u];
}
LL ret = 0;
for ( int i = -dep[s]; i <= dep[s]; ++ i ) {
ret += 1ll * f[s][i] * g[-i];
g[-i] = 0;
}
return ret;
} int main () {
n = rint (); int mxw = 0;
for ( int i = 1, u, v, w; i < n; ++ i ) {
u = rint (), v = rint (), w = rint ();
eset[i] = { u, v, w }, ++ buc[w];
if ( w > mxw ) mxw = w;
}
for ( int i = 2; i <= mxw; ++ i ) buc[i] += buc[i - 1];
for ( int i = 1; i < n; ++ i ) {
eset[i].w = buc[ori[buc[eset[i].w]] = eset[i].w] --;
link ( eset[i].u, eset[i].v, eset[i].w );
link ( eset[i].v, eset[i].u, eset[i].w );
}
BFS ( 1 );
int s = 0, t = 0;
for ( int i = 1; i <= n; ++ i ) {
if ( dep[i] > dep[s] ) s = i;
dep[i] = pre[i] = 0;
}
BFS ( s );
for ( int i = 1; i <= n; ++ i ) if ( dep[i] > dep[t] ) t = i;
for ( int i = dep[s] + dep[t] - 2 >> 1; i --; t = pre[t] );
init ( t ), DP ( t );
g = frepos += dep[t] + 1, frepos += dep[t] + 1;
LL ans = 0;
for ( int i = 1; i < n; ++ i ) ans += ori[i] * update ( down[i] );
printf ( "%lld\n", ans );
return 0;
}

Solution -「LOCAL」画画图的更多相关文章

  1. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  2. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  3. Solution -「LOCAL」过河

    \(\mathcal{Description}\)   一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...

  4. Solution -「LOCAL」Drainage System

    \(\mathcal{Description}\)   合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...

  5. Solution -「LOCAL」Burning Flowers

      灼之花好评,条条生日快乐(假装现在 8.15)! \(\mathcal{Description}\)   给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 ...

  6. Solution -「LOCAL」ZB 平衡树

    \(\mathcal{Description}\)   OurOJ.   维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...

  7. Solution -「LOCAL」舟游

    \(\mathcal{Description}\)   \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...

  8. Solution -「LOCAL」充电

    \(\mathcal{Description}\)   给定 \(n,m,p\),求序列 \(\{a_n\}\) 的数量,满足 \((\forall i\in[1,n])(a_i\in[1,m])\l ...

  9. Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

    \(\mathcal{Description}\)   Link.(完全一致)   给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\r ...

随机推荐

  1. C# string.Format 和 String.Format 的区别

    string.Format 和 String.Format  ,不论是用法还是意思,都是一样的 怎么使用? 通过 占位符来替换 ,类似于 Replace 的操作 string s = string.F ...

  2. js监听网页页面滑动滚动事件,实现导航栏自动显示或隐藏

    /** * 页面滑动滚动事件 * @param e *///0为隐藏,1为显示var s = 1;function scrollFunc(e) { // e存在就用e不存在就用windon.event ...

  3. Centos7 文件权限理解(持续更新)

    后期排版,边学边记边敲 用户详情分析 管理员用户 root  0 虚拟用户 nobody  1-999 普通用户 test001  1000+ 输入ll命令查看当前目录文件详情 根据这张图片可知,目录 ...

  4. vue-json-editor可视化编辑器的介绍与应用

    vue-json-editor可视化编辑器 最近项目中有用到json编辑器,我选用了这款vue的编辑器,看起来也是比较简洁,接下来就具体介绍一下它,以及内部属性. 一.vue-json-editor的 ...

  5. 使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101

    本文要点:设计一条 Spring Boot 最基本的流水线:包括构建.制品上传.部署.使用 Docker 容器运行构建逻辑.自动化整个实验环境:包括 Jenkins 的配置,Jenkins agent ...

  6. 阿里神器 Seata 实现 TCC模式 解决分布式事务,真香!

    今天这篇文章介绍一下Seata如何实现TCC事务模式,文章目录如下: 什么是TCC模式? TCC(Try Confirm Cancel)方案是一种应用层面侵入业务的两阶段提交.是目前最火的一种柔性事务 ...

  7. 机器学习&恶意代码动态检测

    目录 写在前面 1 基于API调用的统计特征 2 API序列特征 3 API调用图 4 基于行为的特征 references: 写在前面 对恶意程序动态检测方法做了概述, 关于方法1和2可以参考阿里云 ...

  8. java基础01-03-注释、标识符、数据类型讲解

    java基础01-注释 java中的注释有三种: 单行注释 多行注释 文件注释 public class helloworld { public static void main(String[] a ...

  9. java日志打印使用指南

    一.简介 日志打印是java代码开发中不可缺少的重要一步. 日志可以排查问题,可以搜集数据 二.常用日志框架 比较常用的日志框架就是logback, 一些老项目会使用log4j,他们用的都是slf4j ...

  10. azure django bug

    azure web app service azure web app service无法部署dhango网站 本地服务器测试代码 实际azure测试 django service 没有部署选项,需要 ...