题目: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的更多相关文章

  1. 【LOJ】#2546. 「JSOI2018」潜入行动

    题解 dp[i][j][0/1][0/1]表示以\(i\)为根的子树,用了\(j\)个,i点选了或者没选,i点被覆盖或没被覆盖 转移比较显然,但是复杂度感觉不太对? 其实转移到100个的时候就使第二维 ...

  2. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  3. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

  4. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  5. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  6. LG4516/LOJ2546 「JSOI2018」潜入行动 树上背包

    问题描述 LG4516 LOJ2546 题解 好一个毒瘤题. hkk:JSOI的签到题 设\(opt[i][j][0/1][0/1]\)代表结点\(i\)的子树,放置\(j\)个,\(i\)放不放,\ ...

  7. LOJ 3092 「BJOI2019」排兵布阵 ——DP

    题目:https://loj.ac/problem/3092 同一个人的不同城堡之间没有什么联系,只是和<=m.所以对每个城堡的 s 个值排序,做一个 f[ i ][ j ] 表示第 i 个城堡 ...

  8. LG1131 「ZJOI2007」时态同步 树形DP

    问题描述 LG1131 题解 正难则反,把从一个点出发到叶子结点看做从叶子结点走到那个点. DP方程很显然. \(\mathrm{Code}\) #include<bits/stdc++.h&g ...

  9. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

随机推荐

  1. 下载并配置jdk

    ①下载jdk安装到本机,这里是jdk8下载地址,请根据自己机子的环境进行下载 https://www.oracle.com/technetwork/java/javase/downloads/jdk8 ...

  2. 不正常退出vim产生swp文件的解决方法

    vi -r README.txt恢复文件,这样上次意外退出没有保存的修改,就会覆盖文件. vi -r查看生成的交换文件 rm .README.txt.swp删除交换文件 搞定!下次打开文件就可以正常编 ...

  3. mybatis的jdbcType和javaType、oracle,MySQL的对应类型

    JdbcType介绍 数据库列字段都是有类型的,不同的数据库有不同的类型.为了表示这些数据类型,Java源码是采用枚举来定义的: public enum JDBCType implements SQL ...

  4. bsxfun.h multiple threads backup

    https://code.google.com/p/deep-learning-faces/source/browse/trunk/cuda_ut/include/bsxfun.h?r=7&s ...

  5. jquery的一个小扩展,读取URL里的参数

    /* *扩展jquery的功能: *读取url中参数的功能,方法的参数是要获取的URL里键; *使用前要先导入jquery.js文件. * */ (function ($) { $.getUrlPar ...

  6. java变量的作用域和基本数据类型转换

    1.变量的作用域 赋值运算符 变量名 = 表达式 列: a = (b+3)+(b-1) 表达式就是符号(如:加号,减号)与操作数(如:b,3)的组合 自动类型转换(隐式类型转换):从小类型到大类型可以 ...

  7. swift3笔记

    备注:这里只是个人的观点,有的地方也是copy,多多指教,个人笔记,有侵犯你们版权的地方还望海涵!!! 个人觉得swift和OC最大的区别就是增加了许多现代化的东西,java里面的闭包,private ...

  8. box-sizing的用法

        默认情况下设置盒子的width是指内容区域,所以在设置边框会使得盒子往外扩张,如果要让css设置的width就是盒子最终的宽度,那么就要设置box-sizing:border-box,     ...

  9. php源代码安装

    1.在官网下载php安装源文件.版本选择5的最新稳定版. [root@trial download]# wget http://cn.php.net/distributions/php-5.5.38. ...

  10. ela的UNASSIGNED索引修复

    1.查找UNASSIGNED未分片的索引: #curl -s "http://localhost:9200/_cat/shards" -u username:passwd | gr ...