题意
给出两个正整数串,每个串中有若干个空格,每个空格等概率地用 1 - m 中的数字填充。问第一个串大于第二个串的概率。
思路
简单dp。
mark 辗转相除法求逆元
LL exgcd(LL a, LL b, LL &x, LL &y){
LL d = a;
if(b != 0){
d = exgcd(b, a % b, y, x);
y = (y - (a / b) * x % mod) % mod;
}else{
x = 1, y = 0;
}
return d;
}
LL mod_inverse(LL a, LL m){
LL x, y;
exgcd(a, m, x, y);
return (m + x % m) % m;
}
链接
http://codeforces.com/contest/935/problem/D
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e5 + 10;
const LL mod = 1e9 + 7;
LL a[maxn], b[maxn];
LL n, m;
LL exgcd(LL a, LL b, LL &x, LL &y){
LL d = a;
if(b != 0){
d = exgcd(b, a % b, y, x);
y = (y - (a / b) * x % mod) % mod;
}else{
x = 1, y = 0;
}
return d;
}
LL mod_inverse(LL a, LL m){
LL x, y;
exgcd(a, m, x, y);
return (m + x % m) % m;
}
LL solve(){
LL p = 0, q = 1, t = 1;
for(int i = 0; i < n; i++){
if(a[i] == 0){
if(b[i] == 0){
p = (q * (m * (m - 1) / 2 % mod) % mod + p * m % mod * m % mod) % mod;
q = q * m % mod;
t = t * m % mod * m % mod;
}else{
p = (q * (m - b[i]) % mod + p * m % mod) % mod;
t = t * m % mod;
}
}else{
if(b[i] == 0){
p = (q * (a[i] - 1) % mod + p * m % mod) % mod;
t = t * m % mod;
}else{
if(a[i] > b[i]){
p += q;
q = 0;
}else if(a[i] < b[i]){
q = 0;
}
}
}
}
return p * mod_inverse(t, mod) % mod;
}
int main(){
while(scanf("%I64d %I64d", &n, &m) == 2){
for(int i = 0; i < n; i++) scanf("%I64d", a + i);
for(int i = 0; i < n; i++) scanf("%I64d", b + i);
printf("%I64d\n", solve());
}
return 0;
}