【BZOJ5314】[JSOI2018]潜入行动(动态规划)

题面

BZOJ

洛谷

题解

不难想到一个沙雕\(dp\),设\(f[i][j][0/1][0/1]\)表示当前点\(i\),子树中一共放了\(j\)个,这个点是否放了,这个是否被覆盖了。

看起来直接合并是\(O(nk^2)\)的QwQ。。。。。

然后我以为是\(O(nk^2)\)的就不会做了嘤嘤嘤。

实际上是\(O(nk)\)的。。。

证明大概是这样的:

考虑什么时候会产生\(O(k^2)\)的贡献,即一个点有两棵子树的大小大于\(k\),而这样子合并次数不会超过\(O(\frac{n}{k})\),所以这部分的复杂度是\(O(nk)\)的。

另外一种情况是一个子树小于\(k\),经过合并之后变成大于\(k\)的子树了,显然对于一个点,如果它的子树小于\(k\),在某次合并之后它的子树就会大于\(k\),并且对于每个点而言,只会在他的某个祖先的地方经历一次这样子的合并,所以这样子均摊每个点会产生\(O(k)\)的贡献。

第三种情况是两个点的子树大小都小于\(k\),合并完之后两者还是小于\(k\)。这个操作理解为每个两个集合中的点一一对应的产生一次贡献,那么盯着某一个特定点考虑,它每次产生的贡献是合并进来的子树大小的,因为在这一部分的过程中子树大小总是小于\(k\),因此每个点产生的贡献也最多是\(O(k)\)的。

综上,在三种合并情况中,每种情况产生的贡献都最多是\(O(nk)\)的,所以全局的复杂度就是\(O(nk)\)。

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100100
#define MOD 1000000007
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,K,f[MAX][101][2][2],size[MAX];
int tmp[101][2][2];
void dfs(int u,int ff)
{
size[u]=1;f[u][0][0][0]=1;f[u][1][1][0]=1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;dfs(v,u);
for(int j=0;j<=size[u]&&j<=K;++j)
for(int k=0;k<=size[v]&&j+k<=K;++k)
{
if(f[u][j][0][0])
{
add(tmp[j+k][0][0],1ll*f[u][j][0][0]*f[v][k][0][1]%MOD);
add(tmp[j+k][0][1],1ll*f[u][j][0][0]*f[v][k][1][1]%MOD);
}
if(f[u][j][0][1])
{
add(tmp[j+k][0][1],1ll*f[u][j][0][1]*(f[v][k][0][1]+f[v][k][1][1])%MOD);
}
if(f[u][j][1][0])
{
add(tmp[j+k][1][0],1ll*f[u][j][1][0]*(f[v][k][0][0]+f[v][k][0][1])%MOD);
add(tmp[j+k][1][1],1ll*f[u][j][1][0]*(f[v][k][1][0]+f[v][k][1][1])%MOD);
}
if(f[u][j][1][1])
{
int s=0;
add(s,f[v][k][0][0]);add(s,f[v][k][0][1]);
add(s,f[v][k][1][0]);add(s,f[v][k][1][1]);
add(tmp[j+k][1][1],1ll*f[u][j][1][1]*s%MOD);
}
}
size[u]+=size[v];
for(int j=0;j<=size[u]&&j<=K;++j)
{
f[u][j][0][0]=tmp[j][0][0];tmp[j][0][0]=0;
f[u][j][0][1]=tmp[j][0][1];tmp[j][0][1]=0;
f[u][j][1][0]=tmp[j][1][0];tmp[j][1][0]=0;
f[u][j][1][1]=tmp[j][1][1];tmp[j][1][1]=0;
}
}
}
int main()
{
n=read();K=read();
for(int i=1,u,v;i<n;++i)u=read(),v=read(),Add(u,v),Add(v,u);
dfs(1,0);
int ans=(f[1][K][0][1]+f[1][K][1][1])%MOD;
printf("%d\n",ans);
return 0;
}

【BZOJ5314】[JSOI2018]潜入行动(动态规划)的更多相关文章

  1. BZOJ5314: [Jsoi2018]潜入行动

    BZOJ5314: [Jsoi2018]潜入行动 https://lydsy.com/JudgeOnline/problem.php?id=5314 分析: 裸树形背包,设\(f[x][i][0/1] ...

  2. [bzoj5314][Jsoi2018]潜入行动_树形背包dp

    潜入行动 bzoj-5314 Jsoi-2018 题目大意:题目链接. 注释:略. 想法: 学长给我们除了一套考试题,三个学长一人一道这是T1. 好吧好吧,傻逼背包...... 复杂度$O(nk)$. ...

  3. BZOJ5314 [Jsoi2018]潜入行动 【背包类树形dp】

    题目链接 BZOJ5314 题解 设\(f[i][j][0|1][0|1]\)表示\(i\)为根的子树,用了\(j\)个监测器,\(i\)节点是否被控制,\(i\)节点是否放置的方案数 然后转移即可 ...

  4. BZOJ5314: [Jsoi2018]潜入行动 (树形DP)

    题意:一棵树选择恰好k个结点放置监听器 每个监听器只能监听相邻的节点 问能使得所有节点被监听的种类数 题解:反正就是很well-known的树形DP了 至于时间复杂度为什么是nk 不会不学 很好想到四 ...

  5. BZOJ5314:[JSOI2018]潜入行动——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5314 https://www.luogu.org/problemnew/show/P4516 ht ...

  6. bzoj 5314: [Jsoi2018]潜入行动

    Description 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY已经联系好了黄金舰队,打算联合所有JSO Ier抵御外星人的进攻.在黄金舰队就位之前,JYY打算事先了解外星人 ...

  7. [loj2546][JSOI2018]潜入行动(树形DP)

    题目描述 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY 已经联系好了黄金舰队,打算联合所有 JSOIer 抵御外星人的进攻. 在黄金舰队就位之前,JYY 打算事先了解外星人的进攻 ...

  8. luogu P4516 [JSOI2018]潜入行动

    LINK:潜入行动 初看题感觉很不可做 但是树形dp的状态过于明显. 容易设\(f_{x,j,l,r}\)表示x为根子树内放了j个设备且子树内都被覆盖l表示x是否被覆盖r表示x是否放设备的方案数. 初 ...

  9. [JSOI2018]潜入行动

    题目 我好菜啊,嘤嘤嘤 原来本地访问数组负下标不会报\(RE\)或者\(WA\),甚至能跑出正解啊 这道题还是非常呆的 我们发现\(k\)很小,于是断定这是一个树上背包 发现在一个点上安装控制器并不能 ...

随机推荐

  1. C#使用ES

    C#如何使用ES Elasticsearch简介 Elasticsearch (ES)是一个基于Apache Lucene(TM)的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为 ...

  2. Spring AOP详细介绍

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  3. ERP & CRM

    ERP流程_百度百科https://baike.baidu.com/item/ERP%E6%B5%81%E7%A8%8B/8099248 CRM_百度百科https://baike.baidu.com ...

  4. maven eclipse 第3方包

    C:\Users\3510\.m2\repository\myjar install:install-file -Dfile=C:\Users\3510\.m2\repository\myjar\al ...

  5. 使用NFS时的一些问题

    当我把nfs服务端共享目录/usr/local/data/test删掉时,在nfs客户端却没办法把之前挂载在这上面的当前从机上的/usr/local/data/test删除,出现 bash: cd: ...

  6. Day 4-11 re正则表达式

    正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持,python里对应的模块是re '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' ...

  7. Python之路-(Django(csrf,中间件,缓存,信号,Model操作,Form操作))

    csrf 中间件 缓存 信号 Model操作 Form操作 csrf: 用 django 有多久,我跟 csrf 这个概念打交道就有久了. 每次初始化一个项目时都能看到 django.middlewa ...

  8. liunx安装nginx

    参考 https://blog.csdn.net/dyllove98/article/details/41120789 1,去官网下载最新的包 官网地址:http://nginx.org/downlo ...

  9. URL & QRcode auto generator

    URL & QRcode auto generator 二维码 npm & qrcode https://www.npmjs.com/package/qrcode https://ww ...

  10. python 编码格式

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...