Solution -「HDU 6643」Ridiculous Netizens
\(\mathcal{Description}\)
Link.
给定一棵含有 \(n\) 个结点的树,点 \(u\) 有点权 \(w_u\),求树上非空连通块的数量,使得连通块内点权积 \(\le m\)。
\(n\le2\times10^3\),\(m\le10^6\),\(w_u\in[1,m]\),数据组数 \(T\le10\)。
\(\mathcal{Solution}\)
很明显是点分,每次考虑跨当前分治重心 \(r\) 的所有连通块对答案的贡献。问题变为:求树上以 \(r\) 为根的满足条件的连通块数量。
一个简单的想法是以子树为子问题树上 DP,但是点权积的状态空间与子树大小完全无关,子树与子树的合并反而更加浪费时间,这提示我们,应该设计一种仅有单点更新的 DP 状态——以 DFN 为子问题 DP。
另一方面,由于运算全部是乘法,可以考虑整除分块的储存方式压缩状态树。令 \(f(u,i)\) 表示当 DFS 进行到某一时刻时,以 \(u\) 子树内已经被搜过的点为最大 DFN 点的连通块中,点权积在整除分块后被映射到 \(i\) 的方案数。进入 \(u\) 子树时用 \(u\) 的父亲更新 \(f(u)\),退出 \(u\) 子树时将 \(f(u)\) 上传给 \(u\) 的父亲。设树的大小为 \(s\),DP 的复杂度为 \(\mathcal O(s\sqrt m)\)。
最终,算法复杂度为 \(\mathcal O(Tn\sqrt m\log n)\)。
\(\mathcal{Code}\)
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
typedef long long LL;
const int MAXN = 2e3, MOD = 1e9 + 7, THRES = 1e3;
int n, m, thres, ecnt, val[MAXN + 5], head[MAXN + 5];
int siz[MAXN + 5], wgt[MAXN + 5], ans;
int f[MAXN + 5][THRES * 2 + 5], g[MAXN + 5][THRES * 2 + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
bool vis[MAXN + 5];
inline void chkmax(int& u, const int v) { u < v && (u = v); }
inline int imin(const int u, const int v) { return u < v ? u : v; }
inline void addeq(int& u, const int v) { (u += v) >= MOD && (u -= MOD); }
inline void link(const int u, const int v) {
graph[++ecnt] = { v, head[u] }, head[u] = ecnt;
graph[++ecnt] = { u, head[v] }, head[v] = ecnt;
}
inline void findG(const int u, const int fa, const int all, int& rt) {
siz[u] = 1, wgt[u] = 0;
for (int i = head[u], v; i; i = graph[i].nxt) {
if (!vis[v = graph[i].to] && v != fa) {
findG(v, u, all, rt), siz[u] += siz[v];
chkmax(wgt[u], siz[v]);
}
}
chkmax(wgt[u], all - siz[u]);
if (!rt || wgt[rt] > wgt[u]) rt = u;
}
inline void getDP(const int u, const int fa) {
int *fcur = f[u], *ffa = f[fa];
rep (i, 0, thres << 1) fcur[i] = 0;
if (!fa) fcur[val[u] <= thres ? val[u] : thres + m / val[u]] = 1;
else {
rep (i, 0, imin(thres, m / val[u])) {
int t = i * val[u];
addeq(fcur[t <= thres ? t : thres + m / t], ffa[i]);
}
rep (i, val[u], thres) {
addeq(fcur[thres + i / val[u]], ffa[thres + i]);
}
}
for (int i = head[u], v; i; i = graph[i].nxt) {
if (!vis[v = graph[i].to] && v != fa) {
getDP(v, u);
}
}
if (fa) rep (i, 0, thres << 1) addeq(ffa[i], fcur[i]);
}
inline void solve(const int u) {
// printf("!%d\n", u);
vis[u] = true, getDP(u, 0);
rep (i, 0, thres << 1) addeq(ans, f[u][i]);
for (int i = head[u], v, rt; i; i = graph[i].nxt) {
if (!vis[v = graph[i].to]) {
findG(v, 0, siz[v], rt = 0), solve(rt);
}
}
}
inline void allClear() {
ans = ecnt = 0;
rep (i, 1, n) head[i] = vis[i] = 0;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m), thres = int(sqrt(1. * m));
allClear();
rep (i, 1, n) scanf("%d", &val[i]);
rep (i, 2, n) { int u, v; scanf("%d %d", &u, &v), link(u, v); }
int rt = 0; findG(1, 0, n, rt);
solve(rt), printf("%d\n", ans);
}
return 0;
}
Solution -「HDU 6643」Ridiculous Netizens的更多相关文章
- Solution -「HDU 6875」Yajilin
\(\mathcal{Description}\) Link.(HDU 裂开了先放个私链 awa.) 在一个 \(n\times n\) 的方格图中,格子 \((i,j)\) 有权值 \(w_ ...
- Solution -「HDU 5498」Tree
\(\mathcal{Description}\) link. 给定一个 \(n\) 个结点 \(m\) 条边的无向图,\(q\) 次操作每次随机选出一条边.问 \(q\) 条边去重后构成生成 ...
- Solution -「HDU 1788」CRT again
\(\mathcal{Description}\) Link. 解同余方程组: \[x\equiv m_i-a\pmod{m_i} \] 其中 \(i=1,2,\dots,n\). \ ...
- Solution -「HDU #6566」The Hanged Man
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个点的树,每个结点有两个权值 \(a\) 和 \(b\).对于 \(k\in[1,m]\),分别求 \[ ...
- [HDU多校]Ridiculous Netizens
[HDU多校]Ridiculous Netizens 点分治 分成两个部分:对某一点P,连通块经过P或不经过P. 经过P采用树形依赖背包 不经过P的部分递归计算 树型依赖背包 v点必须由其父亲u点转移 ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「HDU」Professor Ben
Description 有 \(Q\) 个询问.每次给定一个正整数 \(n\),求它的所有因数的质因数个数的和. Solution 就讲中间的一个 Trick. 我们定义正整数 \(x\) 有 \(f ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
随机推荐
- 第10组 Beta冲刺 (1/5)
1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/p/14012521.html ·作业博客:https://edu.cnblogs.co ...
- JAVA SOCKET 详解
概述 本人在开发学习NETTY的过程中,需要了解很多的网络开发知识,在此我总结一些关于socket的基础知识,大部分是网络总结,在此篇的随笔中记录socket的知识,以便于记录,如有问题欢迎大家斧正. ...
- netty系列之:请netty再爱UDT一次
目录 简介 netty对UDT的支持 搭建一个支持UDT的netty服务 异常来袭 TypeUDT和KindUDT 构建ChannelFactory SelectorProviderUDT 使用UDT ...
- gorm概述与快速入门
特性 全功能 ORM 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承) Create,Save,Update,Delete,Find 中钩子方 ...
- Tomcat服务器和Servlet版本的对应关系
Tomcat服务器和Servlet版本的对应关系 Servlet 程序从2.5版本是现在世面使用最多的版本(xml配置) 到了Servlet3.0后.就是注解版本的Servlet使用
- Kubernetes的Controller进阶(十二)
一.Controller 既然学习了Pod进阶,对于管理Pod的Controller肯定也要进阶一下,之前我们已经学习过的Controller有RC.RS和Deployment,除此之外还有吗,如果感 ...
- Python写春联(turtle版)
Python就好比编程界的瑞士军刀,开箱即用.无所不能.这得益于Python简洁易用的语法,以及丰富的第三方库,你想在电脑上做什么,总能找到事半功倍的第三方库.比如,在这新春佳节之际,用Python来 ...
- Charles和mitmproxy代理设置
1.Charles安装: 1. windows 安装证书 2. 3. 4. 5 pc端设置: Android 手机上设置代理: 先查看pc 端的ip: 2.模拟器进入wifi,按住wifi 3. ...
- 如何美化 Matplotlib 的工具栏和绘图风格
前言 matplotlib 功能十分强大,就是工具栏丑了点.忍了一个学期之后,还是决定自己动手,魔改一波 matplotlib 的工具栏样式.同时给大家分享一下自己按照 MATLAB 写的 matpl ...
- classpath环境变量(JDK5.0之后不建议配置)
classpath的作用: 作用是指定类搜索路径,要使用已经编写好的类,前提当然是能够找到它们了,一旦配置了classpath路径信息的时候,jvm与java编译器都会根据classpath指定的路径 ...