题目描述

https://www.lydsy.com/JudgeOnline/upload/201804/%E6%B9%96%E5%8D%97%E4%B8%80%E8%AF%95%E8%AF%95%E9%A2%98.pdf

题解

大意:给出一张n个点n+x条边的无向连通图,x很小,求出这个图上最大独立集的方案数。

感觉就是NOIP保卫王国那题的加强版吧。

暴力的话,我们可以考虑在图上随便找一颗生成树,然后把非树边连接的点设置为关键点,然后2^x枚举这些点的选择情况,每次做一遍树形dp就好了。

如果做到这里,那么可以自然而然的想到一个优化:虚树。

就是发现在虚树上的非关键点部分的转移相似,所以我们可以预处理出这些东西来。

我们设f[i][0/1]表示i点的所有不包含关键点的子树的答案。

对于关键点到关键点的转移,我们可以设k[i][0/1][0/1]表示关键点i点到i点的第一个关键点祖先的儿子处i点和那个儿子的选择情况的方案数。

这个直接从i点向上跳,边跳边统计答案就可以算出来了。

注意虚树上的LCA点也要标为关键点。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#define N 110009
using namespace std;
typedef long long ll;
const int mod=;
vector<int>vec[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
struct node{int u,v;}ed[];
ll k[N][][],g[N][],f[N][],ans;
int tot,head[N],dfn[N],p[][N],deep[N],a[N],ttt,n,m,st[N],top;
bool vis[N],dy1[N],dy0[N],tag[N];
struct edge{int n,to;}e[N<<];
inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;}
inline void add2(int u,int v){tag[u]=;tag[v]=;vec[u].push_back(v);}////!!!!!!!!!
void dfs(int u,int fa){
dfn[u]=++dfn[];vis[u]=;
for(int i=;(<<i)<=deep[u];++i)p[i][u]=p[i-][p[i-][u]];
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa){
int v=e[i].to;
if(!vis[v]){deep[v]=deep[u]+;p[][v]=u;dfs(v,u);}
else{a[++a[]]=u;a[++a[]]=v;ed[++ttt]=node{u,v};}
}
}
inline bool cmp(int a,int b){return dfn[a]<dfn[b];}
inline int getlca(int a,int b){
if(deep[a]<deep[b])swap(a,b);
for(int i=;i>=;--i)if(deep[a]-(<<i)>=deep[b])a=p[i][a];
if(a==b)return a;
for(int i=;i>=;--i)if(p[i][a]!=p[i][b])a=p[i][a],b=p[i][b];
return p[][a];
}
void predp(int u,int jin){
f[u][]=f[u][]=;tag[u]=;
for(int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(p[][v]!=u||v==jin||tag[v])continue;
predp(v,jin);
f[u][]=f[u][]*(f[v][]+f[v][])%mod;
f[u][]=f[u][]*f[v][]%mod;
}
}
inline void getnum(int x,int y){
k[x][][]=k[x][][]=;
for(int i=x;p[][i]!=y;i=p[][i]){
predp(p[][i],i);
ll xx=k[x][][],yy=k[x][][];
k[x][][]=f[p[][i]][]*(k[x][][]+k[x][][])%mod;
k[x][][]=f[p[][i]][]*xx%mod;
k[x][][]=f[p[][i]][]*(k[x][][]+k[x][][])%mod;
k[x][][]=f[p[][i]][]*yy%mod;
}
}
void prework(int u){
for(int i=;i<vec[u].size();++i){
int v=vec[u][i];
prework(v);getnum(v,u);
}
f[u][]=f[u][]=;
for(int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(p[][v]!=u||tag[v])continue;
predp(v,);
f[u][]=f[u][]*(f[v][]+f[v][])%mod;
f[u][]=f[u][]*f[v][]%mod;
}
}
void dp(int u){
g[u][]=f[u][];g[u][]=f[u][];
if(dy1[u])g[u][]=;if(dy0[u])g[u][]=;
for(int i=;i<vec[u].size();++i){
int v=vec[u][i];
dp(v);
ll k0=(k[v][][]*g[v][]%mod+k[v][][]*g[v][]%mod)%mod,k1=(k[v][][]*g[v][]%mod+k[v][][]*g[v][]%mod)%mod;
g[u][]=g[u][]*(k0+k1)%mod;g[u][]=g[u][]*k0%mod;
}
}
int main(){
n=rd();m=rd();int u,v;
for(int i=;i<=m;++i){
u=rd();v=rd();
add(u,v);add(v,u);
}
dfs(,);sort(a+,a+a[]+,cmp);
a[]=unique(a+,a+a[]+)-a-;
st[top=]=;
for(int i=;i<=a[];++i){
tag[a[i]]=;
if(a[i]==st[top])continue;
int lca=getlca(st[top],a[i]);
if(lca==st[top]){st[++top]=a[i];continue;}
while(top>){
int x=st[top],y=st[top-];
if(dfn[lca]>=dfn[y]){add2(lca,x);top--;break;}
add2(y,x);top--;
}
if(st[top]!=lca)st[++top]=lca;
if(st[top]!=a[i])st[++top]=a[i];
}
while(top>)add2(st[top-],st[top]),top--;
prework();
for(int i=;i<(<<a[]);++i){
for(int j=;j<=a[];++j)if(i&(<<j-))dy1[a[j]]=,dy0[a[j]]=;else dy0[a[j]]=,dy1[a[j]]=;
bool tagg=;
for(int j=;j<=ttt;++j){
int u=ed[j].u,v=ed[j].v;
if(dy1[u]&&dy1[v]){tagg=;break;}
}
if(tagg)continue;
dp();
(ans+=g[][]+g[][])%=mod;
}
cout<<ans;
return ;
}

[HNOI/AHOI2018]毒瘤的更多相关文章

  1. #10 //I [HNOI/AHOI2018]毒瘤

    题解: 80分做法还是听简单的 对于非树边枚举一下端点状态 然而我也不知道为什么就多t了一个点 具体实现上 最暴力的是3^n次 但是我们可以发现对于i不取,j取 i不取,j不取是可以等效成i不取,j没 ...

  2. P4426 [HNOI/AHOI2018]毒瘤

    挺不错的一个题. 题意即为求一个图的独立集方案数. 如果原图是一棵树,可以直接大力f[x][0/1]来dp. 由于非树边很少,考虑2^11容斥,强制某些点必选,然后再O(n)dp,这样应该过不了. 发 ...

  3. Luogu P4426 [HNOI/AHOI2018]毒瘤

    题目 神仙题. 首先我们可以把题意转化为图的独立集计数.显然这个东西是个NP-Hard的. 然后我们可以注意到\(m\le n+10\),也就是说最多有\(11\)条非树边. 我们现在先考虑一下,树上 ...

  4. 题解 [HNOI/AHOI2018]毒瘤

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条边的无向图,问有多少个点集满足点集中任意两点均不存在边相连. \(n\le 10^5,m-n\le 10\),答案对 \(9982443 ...

  5. 洛谷 P4426 - [HNOI/AHOI2018]毒瘤(虚树+dp)

    题面传送门 神仙虚树题. 首先考虑最 trival 的情况:\(m=n-1\),也就是一棵树的情况.这个我相信刚学树形 \(dp\) 的都能够秒掉罢(确信).直接设 \(dp_{i,0/1}\) 在表 ...

  6. [HNOI/AHOI2018]转盘(线段树优化单调)

    gugu  bz lei了lei了,事独流体毒瘤题 一句话题意:任选一个点开始,每个时刻向前走一步或者站着不动 问实现每一个点都在$T_i$之后被访问到的最短时间 Step 1 该题可证: 最优方案必 ...

  7. 【LG4437】[HNOI/AHOI2018]排列

    [LG4437][HNOI/AHOI2018]排列 题面 洛谷 题解 题面里这个毒瘤的东西我们转化一下: 对于\(\forall k,j\),若\(p_k=a_{p_j}\),则\(k<j\). ...

  8. 【题解】Luogu P4436 [HNOI/AHOI2018]游戏

    原题传送门 \(n^2\)过百万在HNOI/AHOI2018中真的成功了qwqwq 先将没门分格的地方连起来,枚举每一个块,看向左向右最多能走多远,最坏复杂度\(O(n^2)\),但出题人竟然没卡(建 ...

  9. [Bzoj5285][洛谷P4424][HNOI/AHOI2018]寻宝游戏(bitset)

    P4424 [HNOI/AHOI2018]寻宝游戏 某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新生 ...

随机推荐

  1. Java web的一些面试题

    1.Tomcat 的优化经验 答:去掉对 web.xml 的监视,把 jsp 提前编辑成 Servlet. 有富余物理内存的情况,加大 tomcat 使用的 jvm 的内存 2.HTTP 请求的 GE ...

  2. ASP.NET WebApi系列

    ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动设备)的 HTTP 服务. ASP.NET Web API 是一种用于在 .NET Framework 上构 ...

  3. intellij idea 2017和Jprofiler 10的集成 报错问题

    本来想用Jprofiler来分析一下自己写的Java项目,以提高代码执行效率和自己的编码能力.结果,官网和网上很多帖子都写了点出session->IDE integrations->选择i ...

  4. 深圳共创力咨询《成功的产品经理DNA》公开课3月29~30日在深圳开课!

    课时:13小时(2天)    成功的产品经理DNA   讲师: 冯老师 时间:2019.03.29~30 举办单位:深圳市共创力企业管理咨询有限公司 举办地点:深圳 [课程背景] 当今时代,供过于求. ...

  5. node配置微信小程序解密消息以及推送消息

    上一篇文章介绍过 微信小程序配置消息推送,没有看过的可以先去查看一下,这里就直接去把那个客服消息接口去解密那个消息了. 在这里我选择的还是json格式的加密. 也就是给小程序客服消息发送的消息都会被微 ...

  6. rocketmq延时消息

    rocketmq提供一种延时消息的解决方案,就是在特定的时间到了,消息才会被投递出去供consumer消费. 总体来是简单的场景是满足了,但是需要注意的是延时的时间是需要按照默认配置的延时级别去配置的 ...

  7. PYTHON定义函数制作简单登录程序(详细)

    环境:python3.* 结构:   dict_name = {} #定义一个字典,后面用到 def newuser(): #定义注册函数 prompt1='login desired:' while ...

  8. mysql字段约束

    为了确保数据的完整性和唯⼀性,关系型数 据库通过约束机制来实现目. 一. unique 唯一性约束    : 值不可重复: 二. not null    非空约束    : 值不可为空: 三. def ...

  9. 数据加密--详解 RSA加密算法 原理与实现

    RSA算法简介 RSA是最流行的非对称加密算法之一.也被称为公钥加密.它是由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adlema ...

  10. cocos web 多端口运行

    cocos2d-js 也是比较普遍的游戏开发工具之一吧,今天想同时启动多个js项目来看下效果,结果百度不到添加端口的方法,又得去翻源码.... cocos run -p web 只要运行在本地就可以启 ...