题面链接

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. 如何在忘记mysql的登录密码时更改mysql登录的密码(window及linux)

    最近一直在边学习边开发java项目,理所当然的就少不了跟数据库打交道了,但是有时候就会脑子一短路,把mysql的登录密码给忘记了,这个时候我们又很急切的需要进到数据库中查看数据,那这个时候要怎么才能改 ...

  2. d-ary heap实现一个快速的优先级队列(C#)

    d-ary heap简介: d-ary heap 是泛化版本的binary heap(d=2),d-ary heap每个非叶子节点最多有d个孩子结点. d-ary heap拥有如下属性: 类似comp ...

  3. 表格 - bootStrap4常用CSS笔记

    [表格标签]   <table> 定义一个表格 <thead> 表格表头 <tbody> 表格主体内容 <tr> 行 <th> 表头列 &l ...

  4. 【python 2.7】获取外部参数

    import sys res_0 = sys.argv[0] res_1 = sys.argv[1] res_2 = sys.argv[2] print res_0 print res_1 print ...

  5. Yii2 创建新项目目录

    默认的高级应用模板包括三个应用 backend – 应用的后台 frontend – 应用的前台 console – 应用的控制台应用 那么如果我们要在增加应用呢?比如在加一个手机端的应用,或者后台和 ...

  6. mkswap命令详解

    基础命令学习目录首页 原文链接:http://blog.51cto.com/arlen99/1743841 mkswap命令用于在一个文件或者设备上建立交换分区.在建立完之后要使用sawpon命令开始 ...

  7. [BUAA_SE_2017]结对项目-数独程序扩展

    结对项目-数独程序扩展 Runnable on x64 Only sudoku17.txt 须放置在可执行文件同目录中,可移步以下链接进行下载 Core-Github项目地址 GUI-Github项目 ...

  8. 20145214《网络对抗》MAL_后门原理与实践

    20145214<网络对抗>MAL_后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 网页上查找资料时有时会不小心点到弹出来的广告,如果这个广告是个钓鱼 ...

  9. 论文《Network in Network》笔记

    论文:Lin M, Chen Q, Yan S. Network In Network[J]. Computer Science, 2013. 参考:关于CNN中1×1卷积核和Network in N ...

  10. javascript数据基本定义以及对象{}和数组[]的含义和使用

    一.基本的数据类型 原始类型(简单数据类型.基本数据类型) Undefined类型: 表示声明了变量但未对其初始化时赋予该变量的值.undefined为Undefined类型下的唯一的一个值. Nul ...