题解

dp[i][j][0/1][0/1]表示以\(i\)为根的子树,用了\(j\)个,i点选了或者没选,i点被覆盖或没被覆盖

转移比较显然,但是复杂度感觉不太对?

其实转移到100个的时候就使第二维满了,之后每多两个点一定会多一个守卫,这个时候会使第二维某些位置开始空了,最后转移其实只有后几维有效

具体优化的方法就是我枚举每个儿子的j的时候,只有j所在的位置有值我们才枚举父亲背包大小来更新

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 100005
#define eps 1e-8
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int N,K; struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE,siz[MAXN];
int dp[MAXN][105][2][2],g[2][4][105];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void update(int &x,int y) {
x = inc(x,y);
}
void dfs(int u,int fa) {
siz[u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs(v,u);
}
}
memset(g,0,sizeof(g));
int cur = 0;
for(int i = 0 ; i <= 3 ; ++i) g[cur][i][0] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
int t = min(K,siz[v]),h = min(K,siz[u] + siz[v]);
memset(g[cur ^ 1],0,sizeof(g[cur ^ 1]));
for(int j = 0 ; j <= t ; ++j) {
if(!dp[v][j][0][0] && !dp[v][j][0][1] && !dp[v][j][1][0] && !dp[v][j][1][1]) continue;
int a[4];
a[0] = dp[v][j][0][1];
a[1] = inc(dp[v][j][0][1],dp[v][j][1][1]);
a[2] = inc(dp[v][j][0][1],dp[v][j][0][0]);
a[3] = inc(inc(dp[v][j][0][0],dp[v][j][0][1]),inc(dp[v][j][1][0],dp[v][j][1][1]));
for(int k = h ; k >= j ; --k) {
update(g[cur ^ 1][0][k],mul(g[cur][0][k - j],a[0]));
update(g[cur ^ 1][1][k],mul(g[cur][1][k - j],a[1]));
update(g[cur ^ 1][2][k],mul(g[cur][2][k - j],a[2]));
update(g[cur ^ 1][3][k],mul(g[cur][3][k - j],a[3]));
} }
siz[u] += siz[v];
cur ^= 1;
}
}
int t = min(K,siz[u]);
for(int i = 0 ; i <= t ; ++i) {
update(g[cur][1][i],MOD - g[cur][0][i]);
update(g[cur][3][i],MOD - g[cur][2][i]);
update(dp[u][i][0][0],g[cur][0][i]);
update(dp[u][i][0][1],g[cur][1][i]);
update(dp[u][i + 1][1][0],g[cur][2][i]);
update(dp[u][i + 1][1][1],g[cur][3][i]);
}
}
void Solve() {
read(N);read(K);
int u,v;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);
add(u,v);add(v,u);
}
dfs(1,0);
out(inc(dp[1][K][1][1],dp[1][K][0][1]));enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

【LOJ】#2546. 「JSOI2018」潜入行动的更多相关文章

  1. LOJ 2546 「JSOI2018」潜入行动——树形DP

    题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...

  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 #2192. 「SHOI2014」概率充电器

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

  8. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  9. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

随机推荐

  1. javaee, javaweb和javase的区别以及各自的知识体系

    javaee, javaweb和javase的区别以及各自的知识体系 来源 https://blog.csdn.net/weixin_39297312/article/details/79454642 ...

  2. BZOJ 2480 && 3239 && 2995 高次不定方程(高次同余方程)

    链接 BZOJ 2480 虽然是个三倍经验题(2333),但是只有上面这道(BZOJ2480)有 p = 1 的加强数据,推荐大家做这道. 题解 这是一道BSGS(Baby Step Giant St ...

  3. 洛谷 P2224 [HNOI2001]产品加工 解题报告

    P2224 [HNOI2001]产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需 ...

  4. CF438D The Child and Sequence(线段树)

    题目链接:CF原网  洛谷 题目大意:维护一个长度为 $n$ 的正整数序列 $a$,支持单点修改,区间取模,区间求和.共 $m$ 个操作. $1\le n,m\le 10^5$.其它数均为非负整数且 ...

  5. 【bzoj1030】 JSOI2007—文本生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=1030 (题目链接) 题意 给出$n$个单词,问有多少个长度为$m$的文本中至少包含一个单词. Sol ...

  6. 51nod 1577 异或凑数

    思路真的是挺巧妙的. 让我惊叹,原来线性基还能这么做?!?! 好吧,这种取若干个数异或凑数的题目怎么能少的了线性基呢? 但是,问题集中在于怎么快速提取一个区间的线性基 暴力n^2 线段树维护线性基?分 ...

  7. box-sizing border-box 的理解

    http://blog.csdn.net/isaisai/article/details/20449827 -webkit-box-sizing: border-box;  则div 设置的宽高将包含 ...

  8. 滚动条事件,当页面滚动到距顶部一定高度时某DIV自动隐藏和显示

    $(function () {                        //绑定滚动条事件              //绑定滚动条事件            $(window).bind(&q ...

  9. 关闭ubuntu dash 方法

    因为ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了.执行时可以把sh换成bash 文件名.sh来执行.成功.dash是什么东西,查了一下,应该也是一种shell, ...

  10. sublime 安装repl插件

    sublime调试Python程序,不能input,但是我们可以借助repl的插件来实现 去GitHub下载repl插件:https://github.com/wuub/SublimeREPL 下载好 ...