给定两个数n,m,接着给定两个长度为n的序列,序列中的数字大小0~m,0代表该位数字未知,取值等可能的为1~m中一个数。
求第一个序列字典序大于第二个的概率p/q(p,q)互质,结果模(1e9+7)
#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f #define MOD 1000000007 using namespace std; typedef long long LL; const int maxn = 1e5 + 10; int inv[2 * maxn]; LL ans; int A[maxn], B[maxn]; int n, m; void init() { inv[0] = 1; inv[1] = 1; for (int i = 2; i < 2 * maxn; i++) { inv[i] = (LL)(MOD - MOD / i) * inv[MOD % i] % MOD; } } LL solve(int t) { if (t == n) { return 0; } else { if (B[t] && A[t] > B[t]) { return 1; } else if (A[t] && A[t] < B[t]) { return 0; } else if (A[t] == B[t] && A[t]) { return solve(t + 1); } else if (!A[t] && B[t]) { return (m - B[t] + solve(t + 1)) % MOD * inv[m] % MOD; } else if (A[t] && !B[t]) { return (A[t] - 1 + solve(t + 1)) % MOD * inv[m] % MOD; } else if (!A[t] && !B[t]) { return (m - 1 + 2 * solve(t + 1)) % MOD * inv[2 * m] % MOD; } } return -1; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &A[i]); for (int i = 0; i < n; i++) scanf("%d", &B[i]); init(); printf("%lld ", solve(0) % MOD); return 0; }