bzoj5315/luoguP4517 [JSOI2018]防御网络(仙人掌,dp)
bzoj5315/luoguP4517 防御网络(仙人掌,dp)
题目描述略(太长了)
题解时间
本题和斯坦纳树无关。
题面保证了是一个仙人掌。。。?
但这个环之间甚至交点都没有。
对于不在环上的边很好弄。
在环上的很难单独考虑。
所以直接考虑一次算出一个环的贡献。
假设我们现在选了一个环上的不止一个点。
那么其中没有被选中的边肯定是连续的一段并且是所有被选中的点分割出的最长的。
这样很容易搞出一个枚举长度 $ l $ 的dp,通过前缀和可以优化到 $ O(n^3) $ 。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long lint;
template<typename TP>inline void read(TP &tar)
{
TP ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')ch=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
tar=ret*f;
}
namespace RKK
{
const int N=211,mo=1000000007;
lint fpow(lint a,lint p){lint ret=1;while(p){if(p&1)ret=ret*a%mo;a=a*a%mo,p>>=1;}return ret;}
struct sumireko{int to,ne;}e[N<<2];int he[N],ecnt=1;
void addline(int f,int t){e[++ecnt].to=t;e[ecnt].ne=he[f],he[f]=ecnt;}
lint b2[N],b1[N];
int n,m;lint ans;
bool lonr[N<<1];
int fa[N],fi[N],sz[N],dep[N];
vector<int> rnd[N];int rcnt;
void getrnd(int x,int anc)
{
rcnt++;
for(int px=x;px!=anc;px=fa[px])
rnd[rcnt].push_back(px),lonr[fi[px]]=1;
rnd[rcnt].push_back(anc);
}
void dfs(int x)
{
sz[x]=1;
for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)if(t!=fa[x])
{
if(!sz[t]) fa[t]=x,dep[t]=dep[x]+1,fi[t]=i>>1,dfs(t),sz[x]+=sz[t];
else if(dep[t]<dep[x])
{
lonr[i>>1]=1;
getrnd(x,t);
}
}
}
int s[N];
lint dp[N],dg[N],ds[N];
void work(int ri)
{
vector<int> &ve=rnd[ri];
int len=ve.size();
for(int i=1;i<len;i++) s[i]=sz[ve[i-1]];s[len]=n;
for(int i=len;i>1;i--) s[i]-=s[i-1];
memset(dp+1,0,8*len);
for(int l=1;l<=len;l++)
{
for(int i=1;i<=l;i++)
{
memset(dg+1,0,8*len),memset(ds+1,0,8*len);
dg[i]=ds[i]=b1[s[i]];
for(int j=i+1;j<=len;j++)
{
dg[j]=b1[s[j]]*(ds[j-1]-ds[max(1,j-l)-1]+mo)%mo;
ds[j]=(ds[j-1]+dg[j])%mo;
}
(dp[l]+=ds[len]-ds[max(i+1,len-l+i)-1]+mo)%=mo;
}
}
for(int i=1;i<=len;++i)
(ans+=(dp[i]-dp[i-1]+mo)*(len-i))%=mo;
}
int Iris()
{
b2[0]=1;for(int i=1;i<=200;i++) b2[i]=(b2[i-1]<<1)%mo,b1[i]=b2[i]-1;
read(n),read(m);for(int i=1,x,y;i<=m;i++) read(x),read(y),addline(x,y),addline(y,x);
dfs(1);
for(int i=1;i<=m;i++)if(!lonr[i])
(ans+=b1[min(sz[e[i<<1].to],sz[e[i<<1|1].to])]*b1[n-min(sz[e[i<<1].to],sz[e[i<<1|1].to])]%mo)%=mo;
for(int i=1;i<=rcnt;i++) work(i);
(ans*=fpow(b2[n],mo-2))%=mo;
printf("%lld\n",ans);
return 0;
}
}
int main(){return RKK::Iris();}
bzoj5315/luoguP4517 [JSOI2018]防御网络(仙人掌,dp)的更多相关文章
- 【BZOJ5315】[JSOI2018]防御网络(动态规划,仙人掌)
[BZOJ5315][JSOI2018]防御网络(动态规划,仙人掌) 题面 BZOJ 洛谷 题解 显然图是仙人掌. 题目给了斯坦纳树就肯定不是斯坦纳树了,,,, 总不可能真让你\(2^n\)枚举点集再 ...
- 洛谷P4517 [JSOI2018]防御网络(dp)
题面 传送门 题解 翻译一下题意就是每次选出一些点,要用最少的边把这些点连起来,求期望边数 我也不知道为什么反正总之就是暴力枚举太麻烦了所以我们考虑贡献 如果一条边是割边,那么它会在图里当且仅当两边的 ...
- BZOJ5315 [JSOI2018]防御网络 【仙人掌 + dp】
题目链接 BZOJ5315 题解 题目好吓人= =点仙人掌 + 斯坦纳树 我们只需求出对于所有选点的方案的斯坦纳树边长总和 \(n\)那么大当然不能状压,但是考虑一下如果这是一棵树,一个方案的贡献就是 ...
- bzoj 5315: [Jsoi2018]防御网络
Description Solution 考虑每一条边的贡献 对于树边,如果两边各存在一个点,那么有贡献,总贡献就是 \((2^{size}-1)*(2^{n-size}-1)\) 分别对应两边的 \ ...
- 【BZOJ-1952】城市规划 [坑题] 仙人掌DP + 最大点权独立集(改)
1952: [Sdoi2010]城市规划 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 73 Solved: 23[Submit][Status][ ...
- 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集
4316: 小C的独立集 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 57 Solved: 41[Submit][Status][Discuss] ...
- BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3467 Solved: 1438[Submit][Status][Discuss] Descripti ...
- 【BZOJ1487】[HNOI2009]无归岛(仙人掌 DP)
题目: BZOJ1487 分析: 题目中给定的图一定是一棵仙人掌(每条边最多属于一个环),证明如下: 先考虑单独一个岛的情况.第一,一个岛一定是一张「弦图」,即任意一个大小超过 3 的环都至少有 1 ...
- bzoj4316小C的独立集(dfs树/仙人掌+DP)
本题有两种写法,dfs树上DP和仙人掌DP. 先考虑dfs树DP. 什么是dfs树?其实是对于一棵仙人掌,dfs后形成生成树,找出非树边(即返祖边),然后dfs后每条返祖边+其所覆盖的链构成了一个环( ...
随机推荐
- Solution -「WF2011」「BZOJ #3963」MachineWorks
\(\mathcal{Description}\) Link. 给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i ...
- HashTable源码学习
一.介绍 1.HashMap和HashTable的区别 1.相同点 二者都实现了Map接口. 底层都是哈西表 2.不同点 Hashtable继承自Dictionary类,而HashMap继承自Abst ...
- Spring Boot数据访问之动态数据源切换之使用注解式AOP优化
在Spring Boot数据访问之多数据源配置及数据源动态切换 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中详述了如何配置多数据源及多数据源之间的动态切换.但是需要读数据库的地方,就 ...
- [LeetCode]LCP 06. 拿硬币
桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中.我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数. 示例 1: 输入:[4,2,1] 输出:4 解释:第一堆力扣 ...
- vmstat监视内存的使用情况
vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可实时动态监视操作系统的虚拟内存.进程.CPU活动. vmstat的语法 vmstat [-V] [-n] [ ...
- vscode分栏显示快捷键
vscode没有默认的分栏快捷键,我们可以自定义,步骤如下: 1.Crtl + k,再Ctrl + s,调出快捷键设置面板 2.在搜索栏输入"视图:",在未定义快捷键的区域找到&q ...
- sql server 数据字符串替换函数
sql server 替换函数 replace 函数参数 REPLACE(string_expression, string_pattern, string_replacement) 1.string ...
- C#爬虫(03):使用Selenium
一.介绍: Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样. 1.Selenium Webdriver(也就是Selenium2 ...
- Python常用内建模块和第三方库
目录 内建模块 1 datetime模块(处理日期和时间的标准库) datetime与timestamp转换 str与datetime转换 datetime时间加减,使用timedelta这个类 转 ...
- Qt:输出为CSV文件时汉字乱码
参考 (18条消息) QT5写csv文件,文件打开后中文显示乱码的问题解决_yanzi150207348的博客-CSDN博客 解决方法 1.在文件开头写一段: #if _MSC_VER >= 1 ...