牛客网 Wannafly挑战赛27 蓝魔法师
蓝魔法师
链接:
https://www.nowcoder.com/acm/contest/215/C
来源:牛客网
题目描述
“你,你认错人了。我真的,真的不是食人魔。”--蓝魔法师
给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),两种方案不同当且仅当存在一条边在一个方案中被删除,而在另一个方案中未被删除,答案对\(998244353\)取模
输入描述:
第一行两个整数\(n\),\(k\), 表示点数和限制
\(2 \le n \le 2000, 1 \le k \le 2000\)
接下来\(n-1\)行,每行包括两个整数\(u\),\(v\),表示\(u\),\(v\)两点之间有一条无向边
输出描述:
共一行,一个整数表示方案数对\(998244353\)取模的结果
长见识了,比赛交了\(8\)次最后终于过了。
树上分组背包,令\(dp_{i,j}\)代表子树\(i\)还剩余\(j\)个点可以连出去时的方案数。
这个转移每个人的写法都可以不一样,说一下我的。
初始化\(dp_{i,1}=1\),代表先强制选\(i\)
对每个子树做\(dp_{i,j}=dp_{s,k}\times dp_{i,j-k}\)表示连接
特判直接砍掉子树的情况,在做子树之前\(dp_{i,j}=dp_{i,j}\times dp_{s,0}\)
做完后再处理一下自己被砍的情况。
注意倒序枚举。
这样写出来是这样的。
void dfs(int now,int fa)
{
dp[now][1]=1;
siz[now]++;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
dfs(v,now);
siz[now]+=siz[v];
for(int r=min(k,siz[now]);r;r--)
{
(dp[now][r]*=dp[v][0])%=mod;
for(int l=1;l<=min(r,siz[v]);l++)
(dp[now][r]+=dp[v][l]*dp[now][r-l])%=mod;
}
}
for(int i=1;i<=min(k,siz[now]);i++) (dp[now][0]+=dp[now][i])%=mod;
}
很不幸的是这样写可以轻松被链卡到\(O(n^3)\)
有一种写法是\(O(n^2)\)的
先枚举子树大小那么大,然后更新当前树
void dfs(int now,int fa)
{
dp[now][1]=1;
siz[now]++;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
dfs(v,now);
for(int r=1;r<=min(k,siz[now]+siz[v]);r++)
f[r]=dp[now][r],(dp[now][r]*=dp[v][0])%=mod;
for(int l=1;l<=siz[v];l++)//物品
for(int r=min(k,siz[now]+l);r>=l+1;r--)//被转移的位置
(dp[now][r]+=dp[v][l]*f[r-l])%=mod;
siz[now]+=siz[v];
}
int rr=min(k,siz[now]);
for(int i=1;i<=rr;i++) (dp[now][0]+=dp[now][i])%=mod;
}
值得一提的是,这个跑法的复杂度是非常严格的,随机数据下进入核心转移的地方只有\(\frac{n(n-1)}{2}\)次,怎么构造都是这样(当然按不考虑\(k\)的大小的剪枝)
为什么呢?考虑一种感性的理解方式。
每一对点,当且仅当在它们的\(\tt{LCA}\)时,能够被转移。
考虑修补一下第一种做法,发现多余的转移是因为权值为\(0\),如果我们这样写,那么复杂度也是一样的了
void dfs(int now,int fa)
{
dp[now][1]=1;
siz[now]++;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
dfs(v,now);
siz[now]+=siz[v];
for(int r=min(k,siz[now]);r;r--)
{
(dp[now][r]*=dp[v][0])%=mod;
if(r==1) continue;
for(int l=siz[v]-siz[now]+r;l<=min(min(k,r-1),siz[v]);l++)
(dp[now][r]+=dp[v][l]*dp[now][r-l])%=mod;
}
}
for(int i=1;i<=k;i++) (dp[now][0]+=dp[now][i])%=mod;
}
2018.10.27
牛客网 Wannafly挑战赛27 蓝魔法师的更多相关文章
- 牛客网 Wannafly挑战赛11 B.白兔的式子-组合数阶乘逆元快速幂
链接:https://www.nowcoder.com/acm/contest/73/B来源:牛客网 B.白兔的式子 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K, ...
- 牛客网 Wannafly挑战赛9 C.列一列-sscanf()函数
C.列一列 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K64bit IO Format: %lld 链接:https://www.now ...
- 牛客网Wannafly挑战赛25A 因子(数论 素因子分解)
链接:https://www.nowcoder.com/acm/contest/197/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...
- 题解——牛客网Wannafly挑战赛23 B-游戏 (SG函数)
前言 比赛的时候没学过SG函数的蒟蒻以为是道结论题,但是不是QwQ 和dummyummy巨佬一起推了快三个小时的规律 最后去问了真正的巨佬__stdcall __stdcall面带微笑的告诉我们,这是 ...
- 牛客网 Wannafly挑战赛8 B.LBJX的三角形
B-LBJX的三角形 链接:https://www.nowcoder.com/acm/contest/57/B来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K, ...
- 牛客网 Wannafly挑战赛8 A.小Y和小B睡觉觉
写了一会不想写了... A-小Y和小B睡觉觉 链接:https://www.nowcoder.com/acm/contest/57/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制: ...
- 牛客网 Wannafly挑战赛11 A.白兔的分身术
水一水博客. 链接:https://www.nowcoder.com/acm/contest/73/A来源:牛客网 A.白兔的分身术 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C ...
- 牛客网 Wannafly挑战赛9 A.找一找-数据处理
好几天没好好学习了(咸鱼晒干了) 把稍微没那么咸鱼的几天前的一场牛客网的比赛稍微看了一下,菜的要死,这一场大数的比较多,都死了. A.找一找 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C ...
- 牛客网 Wannafly挑战赛 C 列一列 简单题 (题目有点坑)
链接:https://www.nowcoder.com/acm/contest/71/C来源:牛客网 题目描述 小W在计算一个数列{An},其中A1=1,A2=2,An+2=An+1+An.尽管他计算 ...
随机推荐
- 各种对list,string操作函数的总结
#encoding=utf-8#reverse,用来反转lista=['aa','bb','cc']a.reverse()print a#['cc', 'bb', 'aa']#不能直接print a. ...
- 项目实战:BBS+Blog项目开发
01-博客系统之功能需求 02-博客系统之表结构设计1 03-博客系统之表结构设计2 04-博客系统之表结构设计3 05-博客系统之表结构设计4 06-博客系统之表机构设计5 07-博客系统之创建系统 ...
- 初学Direct X(8) ——碰撞检测
初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ...
- lintcode373 奇偶分割数组
奇偶分割数组 分割一个整数数组,使得奇数在前偶数在后. 您在真实的面试中是否遇到过这个题? Yes 样例 给定 [1, 2, 3, 4],返回 [1, 3, 2, 4]. 我的方法:设定两个数组,分别 ...
- POJ - 3259
要判断是否有负的权值 #include<iostream> #include<stdio.h> #include<algorithm> #include<st ...
- 【转载】appium 操作汇总
'''.appium api第二弹 锋利的python,这是初稿,2015/1/5 如有错误的地方,请同学们进行留言,我会及时予以修改,尽量整合一份ok的api 作者:Mads Spiral QQ:7 ...
- 【第三章】Shell 变量的数值计算
一.算数运算符 shell中常见的算术运算符: shell中常见的算术命令: 1. 整数运算 方法一:expr expr命令就既可以用于整数运算,也可以用于相关字符串长度.匹配等的运算处理: exp ...
- 关于excle导数据的一些代码笔记
package com.bonc.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutpu ...
- ThinkPHP - 1 - 本地部署
ThinkPHP ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时 ...
- 2.azkaban3.0安装
安装规划安装azkban1.安装配置数据库2.下载安装web server3.安装mulit executor4.安装azkaban插件AZKABAN参数安装出现的问题 安装规划 IP 角色 端口 1 ...