题目传送门(内部题100)


输入格式

  第一行两个整数$n,m$,接下来$m$行每行两个整数$u,v$表示一条$u$连向$v$的边。不保证没有重边和自环。


输出格式

  $n-1$行每行一个整数,第$i$行表示$k=i+1$时的答案。对$998244353$取模。


样例

样例输入:

3 6
1 1
1 2
2 1
2 2
1 3
3 1

样例输出:

4
5


数据范围与提示

数据范围:

  对于$25\%$的数据,$n\leqslant 50$。
  对于另外$20\%$的数据,前$m-1$条边满足$u<v$。
  对于另外$15\%$的数据,不存在$u,v$使得$u!=v$且$\min(u,v)>1$。
  对于$100\%$的数据,$1\leqslant n\leqslant 300,1\leqslant m\leqslant 10^5,1\leqslant u,v\leqslant n$。

提示:

  对于质数$p$和有理数$\frac{a}{b}(b\mod p>0)$,存在恰好一个整数$c$满足$0\leqslant c<p$且$a\equiv bc(\mod p)$,我们称$c$为$\frac{a}{b}$对$p$取模的结果。


题解

概率正着推,期望倒着推。

不妨设$f[i]$表示从$i$出发走到$k$的期望步数,那么可以列出式子:

$$f[i]=\sum \frac{f[j]}{du[i]}+1$$

$f[k]=0$

其中$j$是$i$的所有出边所能到达的点,$du[i]$则为$i$的出度。

那么枚举所有的$k$,然后暴力高斯消元即可拿到$25$分。

考虑优化,因为高斯消元中一段的值可以对很多$k$做贡献,所以我们可以用分治消元。

原理就是:对于区间$[l,r]$,先消$[mid+1,r]$,然后继续递归$[l,mid]$,递归之后再消$[l,mid]$,接着递归$[mid+1,r]$。

时间复杂度:$\Theta(n^3\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mod=998244353;
  4. int n,m;
  5. int du[301],top;
  6. long long Map[301][302],ans[301];
  7. long long qpow(long long x,long long y)
  8. {
  9. long long res=1;
  10. while(y)
  11. {
  12. if(y&1)res=res*x%mod;
  13. x=x*x%mod;y>>=1;
  14. }
  15. return res;
  16. }
  17. void gauss(int x,int l,int r)
  18. {
  19. long long inv=qpow(Map[x][x],mod-2);
  20. for(int i=1;i<=n+1;i++)Map[x][i]=Map[x][i]*inv%mod;
  21. for(int i=1;i<=n;i++)
  22. {
  23. if(i==x)continue;
  24. long long flag=Map[i][x];
  25. for(int j=l;j<=r;j++)
  26. Map[i][j]=(Map[i][j]-Map[x][j]*flag)%mod;
  27. Map[i][n+1]=(Map[i][n+1]-Map[x][n+1]*flag)%mod;
  28. }
  29. }
  30. void solve(int l,int r)
  31. {
  32. if(l==r){ans[l]=(Map[1][n+1]+mod)%mod;return;}
  33. int mid=(l+r)>>1;int wzc[301][302];
  34. for(int i=1;i<=n;i++)
  35. for(int j=1;j<=n+1;j++)
  36. wzc[i][j]=Map[i][j];
  37. for(int i=mid+1;i<=r;i++)gauss(i,l,r);
  38. solve(l,mid);
  39. for(int i=1;i<=n;i++)
  40. for(int j=1;j<=n+1;j++)
  41. Map[i][j]=wzc[i][j];
  42. for(int i=l;i<=mid;i++)gauss(i,l,r);
  43. solve(mid+1,r);
  44. }
  45. int main()
  46. {
  47. scanf("%d%d",&n,&m);
  48. for(int i=1;i<=m;i++)
  49. {
  50. int u,v;
  51. scanf("%d%d",&u,&v);
  52. Map[u][v]++;du[u]++;
  53. }
  54. for(int i=1;i<=n;i++)
  55. {
  56. for(int j=1;j<=n;j++)
  57. Map[i][j]=Map[i][j]*qpow(du[i],mod-2)%mod;
  58. Map[i][i]+=(Map[i][n+1]=-1);
  59. }
  60. solve(1,n);
  61. for(int i=2;i<=n;i++)printf("%d\n",ans[i]);
  62. }

rp++

[CSP-S模拟测试]:走路(期望DP+分治消元)的更多相关文章

  1. BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元

    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...

  2. HDU 2262 Where is the canteen 期望dp+高斯消元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...

  3. hdu4418 Time travel 【期望dp + 高斯消元】

    题目链接 BZOJ4418 题解 题意:从一个序列上某一点开始沿一个方向走,走到头返回,每次走的步长各有概率,问走到一点的期望步数,或者无解 我们先将序列倍长形成循环序列,\(n = (N - 1) ...

  4. 【noi2019集训题1】 脑部进食 期望dp+高斯消元

    题目大意:有n个点,m条有向边,每条边上有一个小写字母. 有一个人从1号点开始在这个图上随机游走,游走过程中他会按顺序记录下走过的边上的字符. 如果在某个时刻,他记录下的字符串中,存在一个子序列和S2 ...

  5. LightOJ 1151 Snakes and Ladders 期望dp+高斯消元

    题目传送门 题目大意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个大小为6的骰子决定.地图上有很多个通道 A可以直接到B,不过A和B大小不确定   而且 ...

  6. P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】

    正题 题目链接:https://www.luogu.com.cn/problem/P4457 题目大意 开始一个人最大生命值为\(n\),剩余\(hp\)点生命,然后每个时刻如果生命值没有满那么有\( ...

  7. ZJUT 1423 地下迷宫(期望DP&高斯消元)

    地下迷宫 Time Limit:1000MS  Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...

  8. Codeforces.24D.Broken robot(期望DP 高斯消元)

    题目链接 可能这儿的会更易懂一些(表示不想再多写了). 令\(f[i][j]\)表示从\((i,j)\)到达最后一行的期望步数.那么有\(f[n][j]=0\). 若\(m=1\),答案是\(2(n- ...

  9. HDU4418 Time travel(期望dp 高斯消元)

    题意 题目链接 Sol mdzz这题真的太恶心了.. 首先不难看出这就是个高斯消元解方程的板子题 \(f[x] = \sum_{i = 1}^n f[to(x + i)] * p[i] + ave\) ...

随机推荐

  1. 【原创】大数据基础之Kudu(5)kudu增加或删除目录/数据盘

    kudu加减数据盘不能直接修改配置fs_data_dirs后重启,否则会报错: Check failed: _s.ok() Bad status: Already present: FS layout ...

  2. vuex用法

    // 配置vuex的步骤 // 1. 运行 cnpm i vuex -S // 2. 导入包 import Vuex from 'vuex' // 3. 注册vuex到vue中 Vue.use(Vue ...

  3. python之file 方法

    file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 1    file.close() close() 方法用于关闭一个已打开的文件.关闭后的文件不能再进行读写操作, 否 ...

  4. 常见排序&查询算法Java代码实现

    1. 排序算法代码实现 /** * ascending sort * 外层循环边界条件:总共需要冒泡的轮数--每一轮都将最大或最小的数冒泡到最后 * 内层循环边界条件:冒泡数字移动的边界--最终数字需 ...

  5. Git切换分支并提交到远程分支

    1. 在本地需要提交的文件同级目录运行git bash 2. 初始化 git 运行环境 $ git init 3. 新建本地分支develop $ git checkout -b decelop 4. ...

  6. 通过WSL使用rsync同步本文件

    1.安装WLS 主要参考Windows10上使用Linux子系统(WSL)这篇文章进行安装,不要通过lxrun /install /y去安装,这种方法安装貌似没有wsl命令. 先把win 10 版本升 ...

  7. kubernetes管理机密信息

    一.启动应用安全信息的保护: Secret介绍: 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ...

  8. PHP中把对象转数组的几个方法

    PHP中把对象转数组的几个方法: 1. //PHP stdClass Object转array function object_array($array) { if(is_object($array) ...

  9. sscanf功能详解(转)

    在处理字符串的程序当中,经常会分析字符串,从一大长串的字符串截取我们需要的数据,这如果通过自己手写函数来分析,虽然可以,但当你知道sscanf的功能,那就自己写函数分析就显得多此一举. 这些函数的使用 ...

  10. Linux之top 监视系统任务的工具

    top 监视系统任务的工具: 和ps 相比,top是动态监视系统任务的工具,top 输出的结果是连续的:  top 命令用法及参数: top 调用方法: top 选择参数 参数: -b  以批量模式运 ...