题面链接

luogu

sol

这篇博是骗访问量的QwQ。

考虑树怎么做,简单容斥。诸如\(f[u][0]=\prod (f[v][0]+f[v][1]),f[u][1]=\prod f[v][0]\)

考虑\(80\)分怎么做(其实只有\(75\)分),暴力枚举多出来的边链接情况,然后\(dp\),复杂度\(O(2^{m-n+1}n)\)。

考虑\(100\)分怎么做,发现只有\(22\)个有用的点,于是建虚树,预处理转移系数,有点复杂。复杂度\(O((m-n+1)*2^{m-n+1}+n)\)

upd:系数大概是个\(f[u][i]=\sum w[u->v][j][i]*f[v][j]\)。自己YY一下就好了,可以拓展到多维系数。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define gt getchar()
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
inline int in()
{
int k=0;char ch=gt;
while(ch<'-')ch=gt;
while(ch>'-')k=k*10+ch-'0',ch=gt;
return k;
}
const int N=2e5+5,YL=998244353;
int f[N][2],fg[N][2],le[N],ri[N],top;
int head[N],to[N<<1],nxt[N<<1],cnt,imp[N];
inline void add(int u,int v)
{
to[++cnt]=v,nxt[cnt]=head[u],head[u]=cnt;
to[++cnt]=u,nxt[cnt]=head[v],head[v]=cnt;
}
inline int MO(const int &a){return a>=YL?a-YL:a;}
int dfn[N],low[N],tt,tsz[N];
void dfs(int u,int pa=0)
{
dfn[u]=++tt;
for(int i=head[u];i;i=nxt[i])
if(to[i]!=pa)
{
if(!dfn[to[i]])dfs(to[i],u),tsz[u]+=tsz[to[i]];
else if(dfn[u]<dfn[to[i]])le[++top]=u,ri[top]=to[i],imp[u]=1;
else imp[u]=1;
}
imp[u]|=tsz[u]>=2;tsz[u]=imp[u]||tsz[u];
}
int o[N];
int Head[N],To[N],Nxt[N];
struct bj
{
int x,y;
bj(){x=0,y=0;}
bj(int _x,int _y):x(_x),y(_y){}
inline bj operator+(const bj &a){return bj(x+a.x,y+a.y);}
inline bj operator*(const int &a){return bj(1ll*x*a%YL,1ll*y*a%YL);}
}W1[50],W2[50],k[N][2];
inline void Add(int u,int v,bj a,bj b){To[++cnt]=v,Nxt[cnt]=Head[u],W1[cnt]=a,W2[cnt]=b,Head[u]=cnt;}
int g[N][2];
int Dfs(int u,int pa=0)
{
g[u][0]=g[u][1]=1;o[u]=1;int pos=0,w;
for(int i=head[u];i;i=nxt[i])
if(!o[to[i]])
{
int v=to[i];w=Dfs(v);
if(!w)g[u][1]=1ll*g[u][1]*g[v][0]%YL,g[u][0]=1ll*g[u][0]*(g[v][1]+g[v][0])%YL;
else if(imp[u])Add(u,w,k[v][0]+k[v][1],k[v][0]);
else k[u][1]=k[v][0],k[u][0]=k[v][1]+k[v][0],pos=w;
}
if(imp[u])k[u][0]=bj(1,0),k[u][1]=bj(0,1),pos=u;
else k[u][0]=k[u][0]*g[u][0],k[u][1]=k[u][1]*g[u][1];
return pos;
}
void dp(int u)
{
f[u][0]=fg[u][1]?0:g[u][0];
f[u][1]=fg[u][0]?0:g[u][1];
for(int i=Head[u];i;i=Nxt[i])
{
int v=To[i];dp(v);int p=f[v][0],q=f[v][1];
f[u][1]=1ll*f[u][1]*(1ll*W2[i].x*p%YL+1ll*W2[i].y*q%YL)%YL;
f[u][0]=1ll*f[u][0]*(1ll*W1[i].x*p%YL+1ll*W1[i].y*q%YL)%YL;
}
}
int main()
{
int n=in(),m=in();
for(int i=1;i<=m;++i)add(in(),in());cnt=0;
dfs(1);imp[1]=1;Dfs(1);
int S=1<<top,ans=0;
for(int i=0;i<S;++i)
{
for(int j=0;j<top;++j)
if(i>>j&1)fg[le[j+1]][1]=fg[ri[j+1]][0]=1;
else fg[le[j+1]][0]=1;
dp(1);ans=MO(ans+MO(f[1][1]+f[1][0]));
for(int j=0;j<top;++j)
if(i>>j&1)fg[le[j+1]][1]=fg[ri[j+1]][0]=0;
else fg[le[j+1]][0]=0;
}
printf("%d\n",ans);
return 0;
}

HNOI2018毒瘤的更多相关文章

  1. 【BZOJ5287】[HNOI2018]毒瘤(动态规划,容斥)

    [BZOJ5287][HNOI2018]毒瘤(动态规划,容斥) 题面 BZOJ 洛谷 题解 考场上想到的暴力做法是容斥: 因为\(m-n\le 10\),所以最多会多出来\(11\)条非树边. 如果就 ...

  2. [bzoj5287] [HNOI2018]毒瘤

    题目描述 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和.毒瘤考虑了n ...

  3. [HNOI2018]毒瘤

    Description 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和 ...

  4. bzoj 5287: [Hnoi2018]毒瘤

    Description Solution \(dfs\) 出一棵生成树之后,多出来的边就都是反祖边了 把反祖边两个端点都拿出来,就会得到最多 \(k=2*(m-n+1)\) 个关键点 除了关键点以外的 ...

  5. BZOJ.5287.[AHOI HNOI2018]毒瘤(虚树 树形DP)

    BZOJ LOJ 洛谷 设\(f[i][0/1]\)表示到第\(i\)个点,不选/选这个点的方案数.对于一棵树,有:\[f[x][0]=\prod_{v\in son[x]}(f[v][0]+f[v] ...

  6. BZOJ5287 HNOI2018毒瘤(虚树+树形dp)

    显然的做法是暴力枚举非树边所连接两点的选或不选,大力dp.考场上写的是最暴力的O(3n-mn),成功比大众分少10分.容斥或者注意到某些枚举是不必要的就能让底数变成2.但暴力的极限也就到此为止. 每次 ...

  7. [BZOJ5287][HNOI2018]毒瘤(虚树DP)

    暴力枚举非树边取值做DP可得75. 注意到每次枚举出一个容斥状态的时候,都要做大量重复操作. 建立虚树,预处理出虚树上两点间的转移系数.也可动态DP解决. 树上倍增.动态DP.虚树DP似乎是这种问题的 ...

  8. 【比赛】HNOI2018 毒瘤

    虚树+dp 直接看zlttttt的强大题解 zlttttt的题解看这里 #include<bits/stdc++.h> #define ui unsigned int #define ll ...

  9. BZOJ 5287: [Hnoi2018]毒瘤 动态dp(LCT+矩阵乘法)

    自己 yy 了一个动态 dp 做法,应该是全网唯一用 LCT 写的. code: #include <bits/stdc++.h> #define ll long long #define ...

随机推荐

  1. JUC——线程同步锁(ReentrantLock)

    ReentrantLock简介 ReentrantLock是一个可重复的互斥锁,又被称为独占锁,可重入的意思是:ReentrantLock锁可以被单个线程多次获取.但是在同一个时间点只能被一个线程锁持 ...

  2. RabbitMQ入门:主题路由器(Topic Exchange)

    上一篇博文中,我们使用direct exchange 代替了fanout exchange,这次我们来看下topic exchange. 一.Topic Exchange介绍 topic exchan ...

  3. xml解析数据信息并实现DBManager操作mysql

      先前一直都是用的直接用加载驱动 然后创建连接进行操作数据 如果我的数据库换了 那么要修改的地方也比较多 不利于维护 所以就想到了将所有配置连接信息都用xml封装起来 以至于我每次都只要修改一下我的 ...

  4. python 基础篇01

    一.python介绍年的圣诞节期间,吉多亿个文件的上传和下载千万张照片被分享,全部用倍年,为了打发圣诞节假期,年,第一个Python编译器诞生.它是用C语言实现的,并能够调用C语言的库文件.从一出生, ...

  5. java中JVM的原理

    转载:https://blog.csdn.net/witsmakemen/article/details/28600127 一.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Jav ...

  6. Scrum立会报告+燃尽图(Final阶段第二次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2481 项目地址:https://coding.net/u/wuyy694 ...

  7. Scrum立会报告+燃尽图(十二月六日总第三十七次):程序功能逻辑优化

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  8. 第39次Scrum会议(12/5)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/12/5 11:35~11:57,总计22min.地点:东北师 ...

  9. 团队项目-NABCD

    用户需求分析与NABCD 模拟经营类(SIM)游戏:玩家模拟经营一家软件公司,平台初步定为Android. Need需求 任何一款游戏都要有自己的定位和目标群体,这些 iiMediaResearch数 ...

  10. Task 6.2站立会议三

    今天我完成了软件的主要聊天界面的视频通话和语音通话的部分功能,过程中遇到很多不会的知识.因为使用的是C#,虽然很容易上手但是还会存在很多不懂得内容.