思路:重要一点,只有前面的数字都相等,才讨论当前的数字情况有意义。ans=∑P*(Q-1)%MOD*qm(m,1e9+5)。
再掌握对分数取模运算以及计算逆元的方法既可以。由费马小定理,有a^(p-1)==1(mod p) → a^(p-2)mod p==inv(a) ,i.e. a对p的逆元= a^(p-2)%p;
复杂度为O(n*sqrt(qe9+7))
AC代码:
#include<bits/stdc++.h>
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
const int MAX_N=1e5+50;
const int MOD=1e9+7;
int a[MAX_N];
int b[MAX_N];
ll qm(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ans%MOD;
}
void solve(){
ll n,m,p=1;//p:前i-1个都相同的概率,因为只有前面都相同的情况下,比较当前的才有意义
ll ans=0;
cin >> n>>m;
for(int i=1;i<=n;++i) cin >> a[i];
for(int i=1;i<=n;++i) cin >> b[i];
for(int i=1;i<=n;i++){
if(a[i]&&b[i]){
if(a[i]>b[i]) {ans+=p,ans%=MOD;break;}
else if(a[i]<b[i]) break;
}
else if(!a[i]&&b[i]){
ans+=p*(m-b[i])%MOD*qm(m,MOD-2); //取模的合理性在于(a+b)%mod=(a+b%mod)%mod,仅仅可以一个取模
ans%=MOD;
p*=qm(m,MOD-2);
p%=MOD;
}
else if(a[i]&&!b[i]){
ans+=p*(a[i]-1)%MOD*qm(m,MOD-2);
ans%=MOD;
p*=qm(m,MOD-2);
p%=MOD;
}
else if(!a[i]&&!b[i]){
ans+=p*(m-1)%MOD*qm(2*m,MOD-2); 这里是化简后的结果
ans%=MOD;
p*=qm(m,MOD-2);
p%=MOD;
}
}
cout << ans%MOD <<endl;
}
int main(void){
FAST;
solve();
return 0;
}