HDU 5507 Graph(dp + 矩阵快速幂)
2016-01-02 22:31
357 查看
题意:
给定一个N≤50,M≤1000的图,求从u出发,到相邻任意点等概率,恰好k步到i的概率给定一个N\le 50, M\le 1000的图, 求从u出发, 到相邻任意点等概率, 恰好k步到i的概率
由于答案为X/Y,输出X∗Y109+5 MOD 109+7由于答案为X/Y,输出X*Y^{10^9+5}\ MOD\ {10^9+7}
分析:
dp[i][j]:=j步到i点的概率,由于每次的转移都一样,可用矩阵快速幂加速dp[i][j]:= j步到i点的概率, 由于每次的转移都一样, 可用矩阵快速幂加速
X∗Y109+5 MOD 109+7=X/Y MOD 109+7X*Y^{10^9+5}\ MOD\ {10^9+7}=X/Y\ MOD\ 10^9+7
转移概率矩阵的∗1/p MOD 109+7,可以变成/p MOD 109+7,即∗p109+5 MOD 109+7转移概率矩阵的*1/p\ MOD\ {10^9+7}, 可以变成/p\ MOD\ {10^9+7}, 即*p^{10^9+5}\ MOD\ {10^9+7}
dp完直接就是答案了,运用了FST求逆元的小知识dp完直接就是答案了, 运用了FST求逆元的小知识
代码:
给定一个N≤50,M≤1000的图,求从u出发,到相邻任意点等概率,恰好k步到i的概率给定一个N\le 50, M\le 1000的图, 求从u出发, 到相邻任意点等概率, 恰好k步到i的概率
由于答案为X/Y,输出X∗Y109+5 MOD 109+7由于答案为X/Y,输出X*Y^{10^9+5}\ MOD\ {10^9+7}
分析:
dp[i][j]:=j步到i点的概率,由于每次的转移都一样,可用矩阵快速幂加速dp[i][j]:= j步到i点的概率, 由于每次的转移都一样, 可用矩阵快速幂加速
X∗Y109+5 MOD 109+7=X/Y MOD 109+7X*Y^{10^9+5}\ MOD\ {10^9+7}=X/Y\ MOD\ 10^9+7
转移概率矩阵的∗1/p MOD 109+7,可以变成/p MOD 109+7,即∗p109+5 MOD 109+7转移概率矩阵的*1/p\ MOD\ {10^9+7}, 可以变成/p\ MOD\ {10^9+7}, 即*p^{10^9+5}\ MOD\ {10^9+7}
dp完直接就是答案了,运用了FST求逆元的小知识dp完直接就是答案了, 运用了FST求逆元的小知识
代码:
[code]// // Created by TaoSama on 2016-01-02 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 50 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; typedef long long LL; struct Matrix { int row, col; LL mat ; void init(int row, int col, bool one = false) { this->row = row; this->col = col; memset(mat, 0, sizeof mat); if(!one) return; for(int i = 1; i <= row; ++i) mat[i][i] = 1; } Matrix operator* (const Matrix& rhs) { Matrix ret; ret.init(row, rhs.col); for(int k = 1; k <= col; ++k) { for(int i = 1; i <= row; ++i) { if(mat[i][k] == 0) continue; for(int j = 1; j <= rhs.col; ++j) { if(rhs.mat[k][j] == 0) continue; ret.mat[i][j] += mat[i][k] * rhs.mat[k][j] % MOD; ret.mat[i][j] %= MOD; } } } return ret; } Matrix operator^ (LL n) { Matrix ret, x = *this; ret.init(row, col, 1); while(n) { if(n & 1) ret = ret * x; x = x * x; n >>= 1; } return ret; } } A; int n, m; LL ksm(LL x, LL n) { LL ret = 1; for(; n; n >>= 1) { if(n & 1) ret = ret * x % MOD; x = x * x % MOD; } return ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { A.init(n, n); while(m--) { int u, v; scanf("%d%d", &u, &v); A.mat[u][v] = 1; } for(int i = 1; i <= n; ++i) { int one = 0; for(int j = 1; j <= n; ++j) one += A.mat[i][j]; for(int j = 1; j <= n; ++j) if(A.mat[i][j]) A.mat[i][j] = ksm(one, MOD - 2); } int q; scanf("%d", &q); while(q--) { int u, k; scanf("%d%d", &u, &k); Matrix B = A ^ k; for(int i = 1; i <= n; ++i) printf("%I64d ", B.mat[u][i]); puts(""); } } return 0; }
相关文章推荐
- iOS音频开发
- Redis学习笔记六:独立功能之 Lua 脚本
- Angularjs + Requirejs 完整的手脚架
- ASP.Net请求处理机制初步探索之旅 - Part 2 核心
- LVS基本命令详解
- mysql常用操作
- 解决:Android Studio 不能预览
- 名次预测(C语言实现)
- C++ Primer 学习笔记——IO类
- LINQ、Lambda 的转换
- JMeter专题系列(四)参数化
- HDOJ 5605 geometry
- malloc free new delete 赋值构造函数相关使用及区别
- spark streaming -- (视频笔记)
- 4.虚拟机ubuntu网络问题汇总
- <LeetCode OJ>Rotate Array【189】
- ABP理论学习之功能管理
- 安卓StateMachine学习笔记--待续
- (Frontend Newbie)JavaScript基础之常见数据类型
- 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法