[bzoj 1758] [Wc2010]重建计划

2023-10-20 20:08
文章标签 计划 bzoj 重建 1758 wc2010

本文主要是介绍[bzoj 1758] [Wc2010]重建计划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果莫名地TLE了可以看一看本文. 数据经过加强后, 以前许多AC代码会超时.
新站没被百度收录, 所以在这里复制一份, 希望能帮到您.
https://chrt.github.io/2017/04/09/bzoj1758-rebuild/

一棵n个结点, 边带权的无根树, 求包含[L,U]条边的简单路径的最大平均权值 (权值和/边数), 保留3位小数. (n≤10^5, 1≤L≤U≤n-1, 边权≤10^6)

虽然AC花费了比想象中更多的功夫, 但我认为数据加强后这是一道不错的题.

这是一个0-1分数规划, 考虑二分一下. 问题简化为, 判断是否存在一条简单路径, 使得

(v(e1)m)+(v(e2)m)++(v(ek)m)0 (k[L,U])

其中 m 是二分的答案.

路径相关问题点分治是个不错的选择. 遍历重心的每一棵子树, 设当前结点v的深度为 d(v) , 对边权重新赋值后到重心的距离为 l(v) , 需要判断是否存在另一棵子树中的某点 u , 使得

Ld(v)d(u)Ud(v)l(u)l(v)

对于所有深度在 [Ld(v),Ud(v)] 的点, 只用考虑距离的数值最大的那个.

这是RMQ问题, 线段树? 两个log好像不太可行……但还是尝试了一下. 本机开O2 3~4s出解, 但是交上去TLE (也许是因为后面将要说的其他原因). 事实上我写了两遍……手敲编译指令, 打错了, 把源代码覆盖了……神奇的是, 之前不开O2无法出解, 重写之后快了不少 (极限数据11s左右).

二分的那个log大概搞不掉了, 大概要换掉线段树. 发现查询的区间有一个特点 - 长度基本是 UL . 能不能借此优化到均摊 O(1) 呢?

看了题解, 才发觉这就是滑动窗口问题, 单调队列即可搞定. 分别维护之前所有子树和当前子树的 深度-长度 数组, 做完滑动窗口后合并两个数组即可.

仍然TLE. 以为是常数问题, 参照题解, 做了一些诸如把二分套到点分治里面的优化, 但是无济于事. 卡了一天……大概新加的那组数据有玄机? 复制了神犇以前的AC代码, 结果也TLE了.

想到有个Discuss页面, 看到有人跟我有相同的疑惑. 谜底揭晓: 单调队列做滑动窗口的线性复杂度, 自变量是待查询的数组大小. 点分治保证递归的深度为 O(lgn) , 但不保证分出来的子树的大小, 深度相近. 所以可以设计这样的数据: 第一棵子树的大小和深度 (从1开始标号) 为n/2, 其余(n/2-1)棵子树大小和深度为1; 每次点分治的时间复杂度退化为 O(n2lgn) . 将子树按深度从小到大排序再做滑动窗口即可解决这个问题.

正确地实现, 时间复杂度为 O(lgUnlgn) .

#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a), i##_end = (b); i < i##_end; ++i)
#define per(i, a, b) for (int i = (a), i##_end = (b); i >= i##_end; --i)using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int N = 1e5;
const double inf = 1e16;
struct Edge {int v, w, nxt;
} E[N*2];
int adj[N + 1];bool g[N + 1];
ii subtree[N];
int depth[N], top, sz[N + 1];
double a[N], b[N];
int tot_a, tot_b;
int L, U;int get_centroid(int u, int p, int n);
void counting_sort(int k[], ii v[], int m, int n);void cal_b(int u, int p, double m, int dep, double len)
{if (dep > U) return;if (tot_b < dep+1) {b[dep] = len;tot_b = dep+1;} elseb[dep] = max(b[dep], len);for (int i = adj[u]; i; i = E[i].nxt) {int v = E[i].v;if (g[v] || v == p) continue;cal_b(v, u, m, dep + 1, len + E[i].w - m);}
}void cal_a()
{rep (i, 1, tot_a)a[i] = max(a[i], b[i]);rep (i, tot_a, tot_b)a[i] = b[i];tot_a = tot_b;
}bool check()
{static int Q[N];int front = 0, rear = 0, j = 0;per (i, tot_b-1, 0) { // [L-i, U-i]while (j < tot_a && j <= U-i) {while (rear > front && a[Q[rear-1]] <= a[j]) --rear;Q[rear++] = j++;}while (front < rear && Q[front] < L-i) ++front;if (front < rear && a[Q[front]] + b[i] >= 0)return true;}return false;
}bool judge(int x, double m)
{tot_a = 1;rep (i, 0, top) {int y = subtree[i].first;tot_b = 1;cal_b(y, x, m, 1, subtree[i].second - m);if (check()) return true;cal_a();}return false;
}int cal_depth(int u, int p)
{int d = -1;for (int i = adj[u]; i; i = E[i].nxt) {int v = E[i].v;if (!g[v] && v != p)d = max(d, cal_depth(v, u));}return d+1;
}void solve(int u, int n, double& l, double _r)
{if (n-1 < L) return;int x = get_centroid(u, 0, n), maxd = 0;g[x] = true;top = 0;for (int i = adj[x]; i; i = E[i].nxt) {int v = E[i].v;if (!g[v]) {subtree[top] = ii(v, E[i].w);maxd = max(maxd, depth[top++] = min(U, cal_depth(v, u)+1));}}counting_sort(depth, subtree, maxd + 1, top);double r = _r;while (r-l >= 1e-4) {double m = (l+r)/2;if (judge(x, m)) l = m;else r = m;}for (int i = adj[x]; i; i = E[i].nxt) {int y = E[i].v;if (!g[y]) solve(y, sz[y]>sz[x] ? n-sz[x] : sz[y], l, _r);}
}inline void add_edge(int u, int v, int w)
{static int ptr = 1;E[ptr] = (Edge){v, w, adj[u]};adj[u] = ptr++;
}int main()
{int n;double l = inf, r = 0;scanf("%d%d%d", &n, &L, &U);rep (i, 0, n-1) {int u, v, w;scanf("%d%d%d", &u, &v, &w);add_edge(u, v, w);add_edge(v, u, w);l = min(l, (double)w);r = max(r, (double)w);}solve(1, n, l, r);printf("%.3f\n", l);return 0;
}int get_centroid(int u, int p, int n)
{int mx = 0, x = 0;sz[u] = 1;for (int i = adj[u]; i; i = E[i].nxt) {int v = E[i].v, ret;if (g[v] || v == p) continue;if ((ret = get_centroid(v, u, n))) x = ret;sz[u] += sz[v];mx = max(mx, sz[v]);}return x ? x : (max(mx, n-sz[u]) <= n/2 ? u : 0);
}void counting_sort(int k[], ii v[], int m, int n)
{static int a[N];static ii b[N];fill_n(a, m, 0);rep (i, 0, n) ++a[k[i]];rep (i, 1, m) a[i] += a[i-1];per (i, n-1, 0) b[--a[k[i]]] = v[i];copy(b, b+n, v);
}

这篇关于[bzoj 1758] [Wc2010]重建计划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/249434

相关文章

《计算机视觉工程师养成计划》 ·数字图像处理·数字图像处理特征·概述~

1 定义         从哲学角度看:特征是从事物当中抽象出来用于区别其他类别事物的属性集合,图像特征则是从图像中抽取出来用于区别其他类别图像的属性集合。         从获取方式看:图像特征是通过对图像进行测量或借助算法计算得到的一组表达特性集合的向量。 2 认识         有些特征是视觉直观感受到的自然特征,例如亮度、边缘轮廓、纹理、色彩等。         有些特征需要通

Claude Enterprise推出计划

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/ 今天推出的Claude Enterprise计划,专为企业打造安全的

为备份驱动器制定备份计划:维护数据的3大方法

时间:2014-02-26 14:49 来源:网管之家 字体:[大 中 小]   您可能已经对您的电脑进行了备份,但其实这样还是远远不够的,其并非如您所认为的那样安全。您企业备份驱动器上的文件可能与您的主系统上的文件一样,容易受到灾难的影响。根据最近流行的恶意软件CryptoLocker的感染途径显示,连接到PC的外置驱动器——辅助硬盘驱动器,例如,用于备份的外部USB硬盘驱动器,可以像

基于开源链动 2 + 1 模式、AI 智能名片与 S2B2C 商城小程序的用户忠诚度计划

摘要:本文深入探讨了在商业环境中执行用户忠诚度计划的创新途径。通过整合开源链动 2 + 1 模式、AI 智能名片以及 S2B2C 商城小程序等先进元素,从提供福利、解决问题和创造赚钱机会三个核心方面展开详细阐述。研究表明,这些新技术和新模式的有机结合,能够为企业打造更具吸引力和影响力的用户忠诚度计划,从而实现商业效益的最大化与可持续发展。 一、引言 在当今竞争激烈且市场环境快速变化的时代,

[置顶] 2014训练计划进阶版

动态规划: 区间dp,树状dp,数位dphdu3555, sgu258, sgu390  队列优化: zoj3399 最小表示法的状态压缩DP: spoj2159  专题链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38881#overview 专题链接: http://acm.hust.edu.cn/vjudg

[置顶] 2014训练计划

每个专题结束后会有5小时的专题赛~ 1、hustOJ目前支持谷歌、火狐浏览器等部分浏览器。 2、欢迎吐槽~ 3、推荐该阶段用书(以下具体算法实现多数可在此书中找到详解):算法竞赛入门经典之训练指南(刘汝佳) 4、题解报告:专题中的题目多是经典题目,百度搜索即有详细解答~ 5、专题相关知识点红字标出,建议先百度红字部分,有助于专题学习~ 6、专题时间会在"ACM 今天你AC了吗?"(12

Windows 一键定时自动化任务神器 zTasker,支持语音报时+多项定时计划执行

简介 zTasker(详情请戳 官网)是一款完全免费支持定时、热键或条件触发的方式执行多种自动化任务的小工具,支持win7-11。其支持超过100种任务类型,50+种定时/条件执行方法,而且任务列表可以随意编辑、排列、移动、更改类型,支持任务执行日志,可覆盖win自带的热键,同时支持任务列表等数据的备份及自动更新等。 简言之,比微软系统自带的任务计划要强好几倍,至少灵活性高多了,能大幅提高电脑使

【Oracle篇】全面理解优化器和SQL语句的解析步骤(含执行计划的详细分析和四种查看方式)(第二篇,总共七篇)

💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨ 💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️ 💖💖💖大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注💖💖💖 SQL优化续新篇,第二篇章启幕时。 优化器内藏奥秘,解析SQL步

2019学习计划

工作三年了,第一年感觉是荒废的,第二年开始学习python,第三年开始自动化 感觉自己会的东西比较少,而且不够深入,流于表面 现制定一下今年大概的学习计划 需持续巩固加强:python、ui自动化、接口自动化、sql等 代码量需提升,敲的不够(重点) 学习: 1.移动端测试,appium等 2.前端知识系统整理学习  3.性能测试 4.docker入门,环境搭建 5.shell

Python(TensorFlow和PyTorch)两种显微镜成像重建算法模型(显微镜学)

🎯要点 🎯受激发射损耗显微镜算法模型:🖊恢复嘈杂二维和三维图像 | 🖊模型架构:恢复上下文信息和超分辨率图像 | 🖊使用嘈杂和高信噪比的图像训练模型 | 🖊准备半合成训练集 | 🖊优化沙邦尼尔损失和边缘损失 | 🖊使用峰值信噪比、归一化均方误差和多尺度结构相似性指数量化结果 | 🎯训练荧光显微镜模型和对抗网络图形转换模型 🍪语言内容分比 🍇Python图像归一化