您的位置:首页 > 其它

HDU 5607 graph

2016-01-03 11:05 429 查看

题意:

给定一个有向图,询问从某个点出发,走 K 步到达其它各点的概率,表示为 x/y,要求 x∗y5+109mod(7+109).

N≤50,M≤1000,Q≤20,u≤N,K≤109

思路:

首先考虑一个一个经典的问题,就是:询问从某个点出发,走 K 步到达其它各点的方案数?

这个问题可以转化为矩阵相乘,所以矩阵快速幂即可解决。但是对于原问题的话,要求 x∗y5+109mod(7+109).

因为 (x/y) mod P = x⋅yP−2 mod P (因为P=7+109 为一个素数,满足费马小定理),所以我们可以把初始的矩阵每个元素值乘上 yP−2,这样也就得到了最终的答案。

for(int i = 1;i <= n;i ++) {
LL now = pw(out[i], 5 + 1e9);
for(int j = 1;j <= n;j ++) {
G[i][j] = (G[i][j] * now) % mod;
}
}


代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <string>
#define PB push_back
#define FT first
#define SD second
#define MP make_pair
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int N = 55, mod = 7 + 1e9;
LL G

;
struct Matrix
{
int n;
LL a

;
Matrix() {
memset(a, 0, sizeof(a));// kidding me .
}
Matrix(int ax){
n = ax;
memset(a, 0, sizeof(a));
}
} ans, A;

Matrix operator * (Matrix a, Matrix b)
{
Matrix tmpans;
tmpans.n = a.n;
for(int i = 1; i <= a.n; i ++){
for(int j = 1; j <= a.n; j ++){
for(int k = 1; k <= a.n; k ++)
tmpans.a[i][j] = (tmpans.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
}
}
return tmpans;
}

void power(int k)
{
while(k){
if(k & 1) ans = ans * A;
A = A * A;
k = k >> 1;
}
}
void init(int k)
{
memcpy(A.a, G, sizeof(A.a));
memset(ans.a, 0, sizeof(ans.a));
for(int i = 1;i <= A.n;i ++) {
ans.a[i][i] = 1;
}
power(k);
}
LL pw(LL a, int k)
{
LL t = 1LL;
while(k) {
if(k & 1) t = (t * a) % mod;
a = (a * a) % mod;
k >>= 1;
}
return t;
}
int out
;
int main()
{
int n, m;
scanf("%d%d", &n, &m);
A.n = n; ans.n = n;
memset(G, 0, sizeof(G));
memset(out, 0, sizeof(out));
while(m --) {
int u, v;
scanf("%d%d", &u, &v);
G[u][v] ++, out[u] ++;
}
for(int i = 1;i <= n;i ++) { LL now = pw(out[i], 5 + 1e9); for(int j = 1;j <= n;j ++) { G[i][j] = (G[i][j] * now) % mod; } }
int Q;
scanf("%d",&Q);
while(Q --) {
int u, k;
scanf("%d%d", &u, &k);
init(k);
for(int i = 1;i <= n;i ++) {
printf("%lld ", ans.a[u][i]);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学