Hetao P10588 十载峥嵘桀骜 题解 [ 紫 ] [ 树的直径 ] [ 矩阵加速 DP ] [ 状态设计优化 ]

news/2025/9/23 18:52:46/文章来源:https://www.cnblogs.com/zhr0102/p/19107621

十载峥嵘桀骜:感觉挺简单的,就是代码处理比较繁琐。

一个最简单的部分分是暴力模拟建图之后跑矩阵快速幂转移,时间复杂度 \(O(n^3\log t)\),随便拼点其他特殊性质就能 68pts 了。

考虑正解,结合树的直径的 DFS 求法,容易注意到在走完第一天后,第二天开始走的就是树的直径了

同时又有“若树上所有边边权均为正,则树的所有直径中点重合”的一个经典结论,因此每天走的路线就是形如:\(u \to root \to v\)。其中 \(u\) 指一个在直径上的叶子,\(root\) 指直径中点,\(v\) 指另一个在直径上的叶子。为了保证每次走的是一个直径,需要保证在以 \(root\) 为根时,\(\bm{u, v}\) 不在一个子树内

由此性质可以对原来的暴力进行一点优化,把以 \(root\) 为根的每个儿子当成矩阵上的一个节点,每次转移相当于从一个儿子转移到另一个儿子。令 \(dp_i\) 表示在节点 \(i\) 方案数(要求 \(i\)\(root\) 的儿子,下文同理),\(x_i\) 表示节点 \(i\) 的子树中在直径上的叶子个数,则从节点 \(a\) 转移到节点 \(b\) 的方程为 \(dp_b\overset{+}{\leftarrow}dp_a\times x_b\)。时间复杂度实质没有改变,菊花就能把它卡飞。

继续观察性质,注意到转移方程只与 \(\bm x\) 的值有关,而 \(\sum x\le n\),所以可以从 \(x\) 的种类数考虑,发现不同的 \(\bm x\) 最多只有 \(\bm{\sqrt n}\)。因此可以将 \(x\) 相同的 \(i\) 进行合并,同时特殊处理 \(x\) 相同的节点之间的转移。此时矩阵上的节点被减少到 \(\sqrt n\) 量级,跑矩阵快速幂即可。时间复杂度 \(O(n\sqrt n\log t)\)

因为直径的中点可能在某条边上,不便于处理,于是可以在每条边上都插入一个虚点,这样就能避免中点在边上的情况。

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi = pair<int, int>;
const int N = 5005, M = 105;
const ll mod = 1e9 + 7;
ll n, kcnt, troot, ksz[N], knum[N], m;
vector<int> g[N];
struct Matrix{ll a[M][M];Matrix(){ memset(a, 0, sizeof(a)); }Matrix operator * (const Matrix & t) const{Matrix res;for(int i = 1; i <= kcnt; i++)for(int k = 1; k <= kcnt; k++)for(int j = 1; j <= kcnt; j++)res.a[i][j] = (res.a[i][j] + a[i][k] * t.a[k][j]) % mod;return res;}
};
Matrix mqpow(Matrix a, ll b)
{Matrix res;for(int i = 0; i <= kcnt; i++) res.a[i][i] = 1;while(b){if(b & 1) res = res * a;b >>= 1;a = a * a;}return res;
}
ll dep[N][N], diam, depmx[N], depcnt[N], scnt[N], stot[N], tot[N];
void dfs(int u, int fa, int anc)
{dep[anc][u] = dep[anc][fa] + 1;for(auto v : g[u]){if(v == fa) continue;dfs(v, u, anc);}
}
void dfs2(int u, int fa, int anc)
{depmx[u] = dep[anc][u];depcnt[u] = 1;for(auto v : g[u]){if(v == fa) continue;dfs2(v, u, anc);scnt[u] = (scnt[u] + scnt[v]) % mod;if(depmx[v] > depmx[u]){depmx[u] = depmx[v];depcnt[u] = depcnt[v];}else if(depmx[v] == depmx[u]) depcnt[u] += depcnt[v];}
}
void solve()
{cin >> n >> m;memset(dep, 0, sizeof(dep));for(int i = 0; i <= 2 * n - 1; i++){g[i].clear();tot[i] = ksz[i] = knum[i] = depmx[i] = depcnt[i] = scnt[i] = stot[i] = 0;}for(int i = 1; i < n; i++){int u, v;cin >> u >> v;g[u].push_back(n + i);g[n + i].push_back(u);g[v].push_back(n + i);g[n + i].push_back(v);}if(n == 1){cout << 1 << "\n";return;}diam = 0;for(int i = 1; i <= 2 * n - 1; i++){dfs(i, 0, i);ll nmx = 0;for(int j = 1; j <= 2 * n - 1; j++){diam = max(diam, dep[i][j]);nmx = max(nmx, dep[i][j]);}if(i > n) continue;for(int j = 1; j <= 2 * n - 1; j++){if(j > n) continue;if(nmx == dep[i][j])scnt[j]++;}        }troot = 0;for(int i = 1; i <= 2 * n - 1; i++){for(int j = 1; j <= 2 * n - 1; j++){if(dep[i][j] == diam){for(int k = 1; k <= 2 * n - 1; k++){if(dep[k][i] + dep[k][j] - 1 == diam && dep[k][i] == dep[k][j]){troot = k;break;}}break;}}if(troot) break;}    dfs2(troot, 0, troot);kcnt = 0;for(auto v : g[troot]){if(depmx[v] != depmx[troot]) continue;tot[depcnt[v]]++;stot[depcnt[v]] = (stot[depcnt[v]] + scnt[v]) % mod;}Matrix dp, sx;for(int i = 0; i <= 2 * n - 1; i++){if(tot[i]){ksz[++kcnt] = tot[i];knum[kcnt] = i;sx.a[kcnt][kcnt] = stot[i];}}for(int i = 1; i <= kcnt; i++){for(int j = 1; j <= kcnt; j++){if(i == j)dp.a[i][j] = knum[i] * (ksz[i] - 1) % mod;elsedp.a[i][j] = knum[j] * ksz[j] % mod;}}sx = sx * mqpow(dp, m - 1);ll ans = 0;for(int i = 1; i <= kcnt; i++)for(int j = 1; j <= kcnt; j++)ans = (ans + sx.a[i][j]) % mod;cout << ans << "\n";
}
int main()
{//freopen("sample.in", "r", stdin);//freopen("sample.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int tid, t;cin >> tid >> t;while(t--) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GO学习记录九——数据库触发器的运用+redis缓存策略

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

顺德网站建设哪家好深圳龙岗网络

问题 今天在使用lombok简化model类时。使用Builder建造者模式。报以下异常 解决办法。 去掉NoArgsConstructor添加AllArgsConstructor源码分析 下图是编译后的源码 只使用Builder会自动创建全参构造器。而添加上NoArgsConstructor后就不会自动产生全参构造器

用 Julia 提取轮廓和字符特征进行验证码识别

验证码图像中的字符常常被干扰线穿插、扭曲变形,导致传统的二值化 + OCR 方法失效。为了解决这类问题,我们可以借助轮廓提取技术,分析字符的几何结构,通过区域形状进行字符识别。本篇博客介绍如何使用 Julia 实现轮…

深入解析:269-基于Python的58同城租房信息数据可视化系统

深入解析:269-基于Python的58同城租房信息数据可视化系统2025-09-23 18:51 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important…

企业网站建设的实践意义哪里有做网站系统的

FastAPI 概述 参考文档&#xff1a; 中文文档轻松上手Python的Web神器&#xff1a;FastAPI教程 介绍 FastAPI 是一个基于 Python 的现代 Web 框架&#xff0c;它具有快速构建高性能 API 的特点。 FastAPI 关键特性: 快速&#xff1a;可与 NodeJS 和 Go 并肩的极高性能&am…

吉林集安市建设局网站哈尔滨网站优化对策

jax可微分编程的笔记(8) 第八章 循环神经网络 神经网络是可微分编程中最为重要的模型构造形式&#xff0c;也是当代 深度学习的基本组成部分&#xff0c;深度学习中的“深度”一词&#xff0c;便是对 神经网络的层数的形容。 8.1 神经网络的生物学基础 通过层层近似&#x…

建设执业资格注册管理中心网站wordpress 两栏

欢迎来到设计模式系列的第三篇文章&#xff01;在前两篇文章中&#xff0c;我们已经学习了设计模式的基本概念以及单例模式的应用。 今天&#xff0c;我们将深入探讨第二个模式——工厂方法模式。 工厂方法模式简介 工厂方法模式是一种创建型设计模式&#xff0c;它提供了一…

你有网站 我做房东 只收佣金的网站电商平台建设费用

概念 ToF 是 Time of Flight 的缩写&#xff0c; ToF 测量法又被称作飞光时间测量法&#xff0c;是通过给目标连续发射激光脉冲&#xff0c;然后用传感器接收在被测平面上反射回来的光脉冲&#xff0c;通过计算光脉冲的飞行往返时间来计算得到确切的目标物距离。因为返回时间很…

网站如何做双语言刷关键词排名seo软件

1、背景 项目上有这样一个需求&#xff0c;前端传文件过来&#xff0c;后端接收后按照特定格式对文件进行重命名。(修改文件名需求其实也可以在前端处理的) //接口类似于下面这个样子 PosMapping("/uploadFile") public R uploadFile(List<MultipartFile> fil…

如何在建设银行网站申购纪念币做网站推广怎么找客户

目录 一.类的声明 二.确定成员变量 三.成员函数 1.带参的构造函数&#xff0c;析构函数&#xff0c;拷贝构造 2.size()与capacity() 3.运算符重载 重载数组下标访问[] 重载 重载比较运算符&#xff08;<&#xff0c; < &#xff0c; > &#xff0c; > …

网站建设名词解释安徽合肥做网站

前言 K8S&#xff0c;全称 Kubernetes&#xff0c;是一个用于管理容器的开源平台。它可以让用户更加方便地部署、扩展和管理容器化应用程序&#xff0c;并通过自动化的方式实现负载均衡、服务发现和自动弹性伸缩等功能。 具体来说&#xff0c;Kubernetes 可以将应用程序打包成…

漳州市网站建设公司北京网站设计公司兴田德润优惠吗

文章目录 Mysql中的排序规则1. 数据库默认的排序规则2. 查看表的排序规则2.1 查看表排序规则2.2 查看字段排序规则 3.修改排序规则3.1 修改库3.2 修改表3.3 修改字段 Mysql中的排序规则 1. 数据库默认的排序规则 mysql8的默认排序方式是 utf8mb4_0900_ai_ci mysql5的默认排序…

湖南网站设计外包哪家好wordpress收益

在Java中&#xff0c;finally块中的代码几乎在任何情况下都会执行&#xff0c;无论是在try块中的代码正常执行完毕&#xff0c;还是遇到异常被catch块捕获时。finally块主要用于执行清理工作&#xff0c;比如释放资源等。然而&#xff0c;存在少数几种情况下finally块中的代码不…

VMware之后下一个消失的永久许可,Citrix Netscaler VPX旧版许可已经失效了!你升级了吗?

VMware之后下一个消失的永久许可,Citrix Netscaler VPX旧版许可已经失效了!你升级了吗?​哈喽大家好,欢迎来到虚拟化时代君(XNHCYL),收不到通知请将我点击星标!“ 大家好,我是虚拟化时代君,一位潜心于互联…

做阀门网站网站建设赚钱流程

Winform使用Webview2创建demo1实现回车导航到指定地址 往期目录参考文档实现1.安装visual studio2.创建单窗口应用3.修改项目中的窗体名称MainForm4.添加按钮5.添加窗口Demo16.在Demo1中添加WebView2 SDK7.在Demo1窗体中选择添加textbox和webview28.在MainForm.cs窗体中添加but…

Windows环境下实现GitLab与Gitee仓库代码提交隔离 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Julia 实现基于模板匹配的验证码识别方法

当验证码图像的字符集较小(如仅包含数字或大写字母),且字体样式统一时,模板匹配是一种简单高效的识别方法。相比通用 OCR 引擎,模板匹配不依赖外部训练数据,能快速匹配字符图像并进行识别。本文将介绍如何用 Jul…

用 Julia 的频域滤波技术识别含干扰线的验证码

在许多验证码图像中,存在大量有意添加的干扰线条、弯曲波纹或背景噪声,这些设计是为了阻止自动识别。传统空间域的二值化方法往往无法彻底去除这些干扰,导致 OCR 误识别或识别失败。频域滤波提供了另一种强大的解决…

网站设计培训学校有哪些十大社区团购平台排名

1、问题 在使用PopupWindow的时候,我们构建好了直接放在Activity的onCreate函数里面直接运行,提示这个错误 Unable to add window -- token null is not valid; is your activity running? 2、原因分析 popupWindow显示依赖activity,并且要等activity所有的生命周期方法…

快速知彼网络网站建设网站建设浏览器不兼容

文章目录 题目描述法一 模拟 题目描述 法一 模拟 初始化一个二维向量&#xff0c;名为matrix&#xff0c;它有n行和n列。向量的每个元素都是一个整数&#xff0c;初始化为0。初始化二维向量的语法如下&#xff1a;vector<vector<int>> matrix(n, vector<int>…