LOJ 2546 「JSOI2018」潜入行动——树形DP
题目:https://loj.ac/problem/2546
dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖。
注意 s1<=s0 ,别弄出负角标。
用 if 判断一下,如果有值再转移,会快非常多。
复杂度是 O(n*k) 的。证明:https://www.cnblogs.com/cjyyb/p/10416839.html
先约定如果一个小于 k 的子树和一个大于 k 的子树合并,在小于 k 的子树那里看复杂度。
1.两个小于 k 的子树 cr 和 v 合并,且合并完之后还是小于 k 的;
对于 cr 里的每个点,要和 v 的每个点产生贡献。虽然和很多 v 都这样做了,但这些 v 的大小加起来小于 k (因为规定合并完还是小于 k ),所以一个点贡献 O(k) 次。
如果合并完大于 k ,就在 “一个小于 k 的子树和一个大于 k 的子树合并” 的部分考虑复杂度了。
2.一个小于 k 的子树 cr 和一个大于 k 的子树 v 合并。
对于 cr 里的每个点,此时都要进行 O(k) 次贡献。合并完之后 cr 的大小变成大于 k ,所以这种贡献,每个点只会经历一次。
3.一个大于 k 的子树 cr 和一个大于 k 的子树 v 合并。
产生 k2 的贡献。如果是两个大小为 k 的子树,合并之后大小变成 2*k ;再合并进来一个大小为 k 的,大小就变成 3*k ;即这种合并最多 \( \frac{n}{k} \) 次。
综上,复杂度是 O(n*k) 的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=1e5+,M=,mod=1e9+;
int upt(int x){while(x>=mod)x-=mod;while(x<)x+=mod;return x;} int n,k,hd[N],xnt,to[N<<],nxt[N<<];
int siz[N],dp[N][M][][],tp[][];
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
void cz(int &x,int y){x=upt(x+y);}
void dfs(int cr,int fa)
{
dp[cr][][][]=dp[cr][][][]=; siz[cr]=;
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa)
{
dfs(v,cr);
for(int s0=Mn(k,siz[cr]+siz[v]);s0>=;s0--)
{
tp[][]=tp[][]=tp[][]=tp[][]=;
for(int s1=Mx(,s0-siz[cr]),lm=Mn(s0,Mn(siz[v],k));s1<=lm;s1++)
{
int d=s0-s1;
if(dp[cr][d][][])
{
cz(tp[][],(ll)dp[cr][d][][]*dp[v][s1][][]%mod);
cz(tp[][],(ll)dp[cr][d][][]*dp[v][s1][][]%mod);
}
if(dp[cr][d][][])
cz(tp[][],(ll)dp[cr][d][][]*(dp[v][s1][][]+dp[v][s1][][])%mod);
if(dp[cr][d][][])
{
cz(tp[][],(ll)dp[cr][d][][]*(dp[v][s1][][]+dp[v][s1][][])%mod);
cz(tp[][],(ll)dp[cr][d][][]*(dp[v][s1][][]+dp[v][s1][][])%mod);
}
if(dp[cr][d][][])
{
cz(tp[][],(ll)dp[cr][d][][]
*((ll)dp[v][s1][][]+dp[v][s1][][]+dp[v][s1][][]+dp[v][s1][][])%mod);
}
}
for(int f0=;f0<=;f0++)
for(int f1=;f1<=;f1++)
dp[cr][s0][f0][f1]=tp[f0][f1];
}
siz[cr]+=siz[v];
}
}
int main()
{
n=rdn();k=rdn();
for(int i=,u,v;i<n;i++)
u=rdn(),v=rdn(),add(u,v),add(v,u);
dfs(,);
printf("%d\n",upt(dp[][k][][]+dp[][k][][]));
return ;
}
LOJ 2546 「JSOI2018」潜入行动——树形DP的更多相关文章
- 【LOJ】#2546. 「JSOI2018」潜入行动
题解 dp[i][j][0/1][0/1]表示以\(i\)为根的子树,用了\(j\)个,i点选了或者没选,i点被覆盖或没被覆盖 转移比较显然,但是复杂度感觉不太对? 其实转移到100个的时候就使第二维 ...
- LOJ 2550 「JSOI2018」机器人——找规律+DP
题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...
- LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流
题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...
- LOJ 2551 「JSOI2018」列队——主席树+二分
题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...
- LOJ 2547 「JSOI2018」防御网络——思路+环DP
题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...
- LG4516/LOJ2546 「JSOI2018」潜入行动 树上背包
问题描述 LG4516 LOJ2546 题解 好一个毒瘤题. hkk:JSOI的签到题 设\(opt[i][j][0/1][0/1]\)代表结点\(i\)的子树,放置\(j\)个,\(i\)放不放,\ ...
- LOJ 3092 「BJOI2019」排兵布阵 ——DP
题目:https://loj.ac/problem/3092 同一个人的不同城堡之间没有什么联系,只是和<=m.所以对每个城堡的 s 个值排序,做一个 f[ i ][ j ] 表示第 i 个城堡 ...
- LG1131 「ZJOI2007」时态同步 树形DP
问题描述 LG1131 题解 正难则反,把从一个点出发到叶子结点看做从叶子结点走到那个点. DP方程很显然. \(\mathrm{Code}\) #include<bits/stdc++.h&g ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
随机推荐
- Anaconda 创建环境
2019-03-25 17:10:51 Anaconda 给不同的项目创建不同的环境真的非常重要,最近在使用flask的时候在base环境中安装flask-bootstrap,竟然将我原本的py3.7 ...
- npm2 与 npm3的包版本管理
npm2采用严格的包依赖模式 npm install name@1.2.* ---- 1.2.0 <= version <= 1.2.9 npm install name@1.* ---- ...
- MVC实战之排球计分(六)—— 使用EF框架,创建Controller,生成数据库。
在上篇博客我们写到,此软件的数据库连接我们使用的是EF框架,code first模式下, 通过模型类,在创建controller的时候直接生成数据库,完成数据库的连接,与操作. 在使用EF框架之前,我 ...
- ES6中export与export default的区别
首先要知道export,import ,export default是什么 ES6模块主要有两个功能:export和importexport用于对外输出本模块(一个文件可以理解为一个模块)变量的接口i ...
- Hexo-使用
hexo 写新文章 创建新的文章 ``` bash $ hexo new "Hexo-使用" ``` 生成md文件 ``` bash $ hexo generate ``` 写文章 ...
- MySQL 排名、分组后组内排名、取各组的前几名 及排名后更新插入数据表中
一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...
- boost range zhuan
Officialhttp://67.223.234.84/boost_doc/libs/range/doc/utility_class.html#sub_range http://blog.sina. ...
- C# 远程传输File文件
/// <summary> /// 向论坛传图片文件 /// </summary> /// <param name="filePath">< ...
- leetcode 总结 动态规划问题小结
动态规划 动态规划对于子问题重叠的情况特别有效,因为它将子问题的解保存在表格,当需要某个子问题的解 时,直接取值即可,从而避免重复计算. 基本思路与策略 基本思想与分治法类似,也是将带求解的问题分解为 ...
- Java中的值传递与引用传递
1.基本类型和引用类型在内存中的保存 Java中数据类型分为两大类,基本类型和对象类型.相应的,变量也有两种类型:基本类型和引用类型. 基本类型的变量保存原始值,即它代表的值就是数值本身: 而引用类型 ...