HNOI2018毒瘤
题面链接
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毒瘤的更多相关文章
- 【BZOJ5287】[HNOI2018]毒瘤(动态规划,容斥)
[BZOJ5287][HNOI2018]毒瘤(动态规划,容斥) 题面 BZOJ 洛谷 题解 考场上想到的暴力做法是容斥: 因为\(m-n\le 10\),所以最多会多出来\(11\)条非树边. 如果就 ...
- [bzoj5287] [HNOI2018]毒瘤
题目描述 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和.毒瘤考虑了n ...
- [HNOI2018]毒瘤
Description 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和 ...
- bzoj 5287: [Hnoi2018]毒瘤
Description Solution \(dfs\) 出一棵生成树之后,多出来的边就都是反祖边了 把反祖边两个端点都拿出来,就会得到最多 \(k=2*(m-n+1)\) 个关键点 除了关键点以外的 ...
- 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] ...
- BZOJ5287 HNOI2018毒瘤(虚树+树形dp)
显然的做法是暴力枚举非树边所连接两点的选或不选,大力dp.考场上写的是最暴力的O(3n-mn),成功比大众分少10分.容斥或者注意到某些枚举是不必要的就能让底数变成2.但暴力的极限也就到此为止. 每次 ...
- [BZOJ5287][HNOI2018]毒瘤(虚树DP)
暴力枚举非树边取值做DP可得75. 注意到每次枚举出一个容斥状态的时候,都要做大量重复操作. 建立虚树,预处理出虚树上两点间的转移系数.也可动态DP解决. 树上倍增.动态DP.虚树DP似乎是这种问题的 ...
- 【比赛】HNOI2018 毒瘤
虚树+dp 直接看zlttttt的强大题解 zlttttt的题解看这里 #include<bits/stdc++.h> #define ui unsigned int #define ll ...
- BZOJ 5287: [Hnoi2018]毒瘤 动态dp(LCT+矩阵乘法)
自己 yy 了一个动态 dp 做法,应该是全网唯一用 LCT 写的. code: #include <bits/stdc++.h> #define ll long long #define ...
随机推荐
- Python之元类详解
一.引子 元类属于Python面向对象编程的深层魔法,99%的人都不得要领,一些自以为搞明白元类的人其实也是自圆其说,点到为止,从队元类的控制上来看就破绽百出,逻辑混乱: 二.什么是元类 一切源自于一 ...
- happybase(TSocket read 0 bytes)
关于报错happybase 是使用python连接hbase的一个第三方库,目前基于thrift1 .在使用过程中经常碰到报错 TTransportException(type=4, message= ...
- JavaScript学习笔记(七)—— 再说函数
第八章 函数 1 函数声明和函数表达式 差别一:函数声明:函数在执行代码前被创建:函数表达式是在运行阶段执行代码时创建: 差别二:函数声明创建一个与函数同名的变量,并让她指向函数:使用函数表达式,不给 ...
- Harbor 学习分享系列2 - Harbor项目介绍
云盘链接 链接:https://pan.baidu.com/s/19yZCZMijf1c3rTwYOqiZzw 密码:netv 通过本文无法把本文中的实验进行成功,请联系作者本人,作者会录制视频发送给 ...
- 15 Puzzle (4乘4谜题) IDA*(DFS策略与曼哈顿距离启发) 的C语言实现
大家好!这是我的第一篇博客,由于之前没有撰写博客的经验,并且也是初入计算机和人工智能领域,可能有些表述或者理解不当,还请大家多多指教. 一.撰写目的 由于这个学期在上算法与数据结构课程的时候,其中一个 ...
- 机器装多个版本php,并安装redis插件报错【已解决】
机器原版本php5.5.3 适应新的框架安装了7.1.12 期间遇到的小问题就是安装 redis插件的时候,总报错,报错如下: Starting php-fpm [02-Jan-2019 10:15: ...
- No.1011_第八次团队会议
罗老师和Bigman助教: 一直以来没看博客页面,我们的博客负责人不是没写博客,而是不小心把博客发到草稿上了.. 请您再次看一下我们的博客,并批评指正! 今天大家的情绪依旧很低落,离第一轮迭代完成距离 ...
- C++作业 一
计算圆面积 Github:https://github.com/tinghaishuo/object-oriented/tree/master/circle
- b6
吴晓晖(组长) 过去两天完成了哪些任务 对手写输入进行了重构,然后重新捋了一下bayes的思路 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员:刘帅珍 过去两天完 ...
- HDU 4026 Unlock the Cell Phone 状压dp(类似TSP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4026 Unlock the Cell Phone Time Limit: 6000/3000 MS ...