P4321-随机漫游【状压dp,数学期望,高斯消元】
正题
题目链接:https://www.luogu.com.cn/problem/P4321
题目大意
给出\(n\)个点\(m\)条边的一张无向图,\(q\)次询问。
每次询问给出一个点集和一个起点,求从起点出发随机游走经过所有点集的期望步数。
\(n\in[1,18],m\in[1,\frac{n(n-1)}{2}],q\in[1,10^5]\)
解题思路
首先\(n\)很小可以状压经过点的状态,然后因为这个询问是给出起始状态所以需要倒推。设\(f_{s,x}\)表示目前状态是\(s\),在点\(x\),覆盖所有点的期望次数。
那么有方程
\]
然后\(S\)不同的当常数,相同的高斯消元转移即可。
时间复杂度\(O(2^nn^3)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=19,M=1e5+10,P=998244353;
ll n,m,q,inv[M],deg[N],a[N][N],f[1<<N][N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
namespace G{
ll a[N][N],b[N];
void clear(){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
return;
}
void solve(ll *f){
for(ll i=1;i<=n;i++){
ll p=i;
for(ll j=i;j<=n;j++)
if(a[j][i]){p=j;break;}
swap(a[i],a[p]);swap(b[i],b[p]);
ll inv=power(a[i][i],P-2);
for(ll j=i;j<=n;j++)
a[i][j]=a[i][j]*inv%P;
b[i]=b[i]*inv%P;
for(ll j=i+1;j<=n;j++){
int rate=P-a[j][i];
for(ll k=i;k<=n;k++)
a[j][k]=(a[j][k]+a[i][k]*rate%P)%P;
b[j]=(b[j]+b[i]*rate%P)%P;
}
}
for(ll i=n;i>=1;i--){
for(ll j=i+1;j<=n;j++)
b[i]=(b[i]-a[i][j]*b[j]%P+P)%P;
f[i]=b[i];
}
return;
}
}
signed main()
{
scanf("%lld%lld",&n,&m);inv[1]=1;
for(ll i=2;i<=m;i++)
inv[i]=P-(P/i)*inv[P%i]%P;
for(ll i=1;i<=m;i++){
ll x,y;
scanf("%lld%lld",&x,&y);
a[x][y]++;a[y][x]++;
deg[x]++;deg[y]++;
}
ll MS=(1<<n);
for(ll s=MS-2;s>=0;s--){
G::clear();
for(ll i=1;i<=n;i++)
if((s>>i-1)&1)G::a[i][i]=P-1,G::b[i]=P-1;
for(ll i=1;i<=n;i++){
if(!((s>>i-1)&1))continue;
for(ll j=1;j<=n;j++){
if(!a[i][j])continue;
if((s|(1<<j-1))==s)
(G::a[i][j]+=inv[deg[i]])%=P;
else (G::b[i]+=P-inv[deg[i]]*f[s|(1<<j-1)][j]%P)%=P;
}
}
G::solve(f[s]);
}
scanf("%lld",&q);
while(q--){
ll m,s=0,x;scanf("%lld",&m);
for(ll i=1;i<=m;i++)
scanf("%lld",&x),s|=(1<<x-1);
scanf("%lld",&x);
printf("%lld\n",f[(MS-1-s)|(1<<x-1)][x]);
}
return 0;
}
P4321-随机漫游【状压dp,数学期望,高斯消元】的更多相关文章
- BZOJ1076 [SCOI2008]奖励关 【状压dp + 数学期望】
1076: [SCOI2008]奖励关 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 3074 Solved: 1599 [Submit][Sta ...
- UVa 10828 Back to Kernighan-Ritchie (数学期望 + 高斯消元)
题意:给定一个 n 个结点的有向图,然后从 1 结点出发,从每个结点向每个后继结点的概率是相同的,当走到一个没有后继结点后,那么程序终止,然后问你经过每个结点的期望是次数是多少. 析:假设 i 结点的 ...
- 【BZOJ】1076: [SCOI2008]奖励关(状压dp+数学期望)
http://www.lydsy.com/JudgeOnline/problem.php?id=1076 有时候人蠢还真是蠢.一开始我看不懂期望啊..白书上其实讲得很详细的,什么全概率,全期望(这个压 ...
- BZOJ 3143 游走 | 数学期望 高斯消元
啊 我永远喜欢期望题 BZOJ 3143 游走 题意 有一个n个点m条边的无向联通图,每条边按1~m编号,从1号点出发,每次随机选择与当前点相连的一条边,走到这条边的另一个端点,一旦走到n号节点就停下 ...
- 【BZOJ】2337: [HNOI2011]XOR和路径 期望+高斯消元
[题意]给定n个点m条边的带边权无向连通图(有重边和自环),在每个点随机向周围走一步,求1到n的期望路径异或值.n<=100,wi<=10^9. [算法]期望+高斯消元 [题解]首先异或不 ...
- [BZOJ3143][HNOI2013]游走(期望+高斯消元)
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3576 Solved: 1608[Submit][Status ...
- 【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元
[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解] ...
- loj2542 「PKUWC2018」随机游走 【树形dp + 状压dp + 数学】
题目链接 loj2542 题解 设\(f[i][S]\)表示从\(i\)节点出发,走完\(S\)集合中的点的期望步数 记\(de[i]\)为\(i\)的度数,\(E\)为边集,我们很容易写出状态转移方 ...
- loj2542 「PKUWC2018」随机游走 MinMax 容斥+树上高斯消元+状压 DP
题目传送门 https://loj.ac/problem/2542 题解 肯定一眼 MinMax 容斥吧. 然后问题就转化为,给定一个集合 \(S\),问期望情况下多少步可以走到 \(S\) 中的点. ...
随机推荐
- javaWeb常用面试题
JDBC JDBC访问数据库的基本步骤是什么? 加载驱动 通过DriverManager对象获取连接对象Connection 通过连接对象获取会话,有2种方式Statement.PreparedSta ...
- Quartz任务调度(5)TriggerListener分版本超详细解析
TriggerListener 在我们的触发器监听器中,也包含了一系列监听方法 方法 说明 getName() 定义并返回监听器的名字 triggerFired() 当与监听器相关联的 Trigger ...
- 二:Servlet简介
一.Servlet简介 1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是 ...
- python turtle的使用
turtle.pendown() # 放下画笔 turtle.penup() # 抬起画笔 turtle.pensize(int) # 设置画笔宽度,值为整数型 turtle.forward(f ...
- 图解Java 垃圾回收机制
摘要: Java技术体系中所提倡的 自动内存管理 最终可以归结为自动化地解决了两个问题:给对象分配内存 以及 回收分配给对象的内存,而且这两个问题针对的内存区域就是Java内存模型中的 堆区.关于对象 ...
- 不用调整Nginx,SpringBoot也能解决前端访问的跨域问题
1.什么情况下会出现跨域问题 通常,在前端工程师的开发过程中,往往在本地机器启动前端服务, 而调用的后端接口服务是在另外一台机器运行,这时就会出现跨域问题,让接口无法调通. 而到了测试环境和生产环境, ...
- C# - 习题04_分析代码写出结果i1、i2、c.i、str、c.str
时间:2017-08-23 整理:byzqy 题目:分析如下代码,写出程序输出结果. 文件:Class1.cs using System; namespace Interview3 { class C ...
- Java线程池工作原理
前言 当项目中有频繁创建线程的场景时,往往会用到线程池来提高效率.所以,线程池在项目开发过程中的出场率是很高的. 那线程池是怎么工作的呢?它什么时候创建线程对象,如何保证线程安全... 什么时候创建线 ...
- group by分组查询
有如下数据: 一个简单的分组查询的案例 按照部门编号deptno分组,统计每个部门的平均工资. select deptno,avg(sal) avgs from emp group by deptno ...
- BUUCTF-[网鼎杯 2020 青龙组]AreUSerialz
BUUCTF-[网鼎杯 2020 青龙组]AreUSerialz 看题 <?php include("flag.php"); highlight_file(__FILE__) ...