1. 程式人生 > >codeforces 935D Fafa and Ancient Alphabet逆元加dp

codeforces 935D Fafa and Ancient Alphabet逆元加dp

div mst ans force 推出 memset namespace define mem

這道題題意為給兩個數,有n位,數是m進制,為零的位置可以填入1到m的任何數,求第一個數大於第二個數個概率

設概率為x/y,這題答案為(x/y)%mod,可以拆成兩部分x%mod*(1/y)%mod,x%mod部分可以用dp推出

,(1/y)%mod的部分可以用n*y=1(%mod)求出答案就是n,n就是y關於mod的逆元

逆元可以由費馬小定理得出結論n=y^(mod-2);

也可以用歐幾裏得定理

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <stdio.h>
 5
#include <math.h> 6 using namespace std; 7 const int INF = 0x3f3f3f3f; 8 typedef long long LL; 9 10 void extra_gcd(LL a, LL b, LL &x, LL &y, LL &d) 11 { 12 if(b == 0) 13 { 14 d = a; 15 x = 1; 16 y = 0; 17 } 18 else 19 { 20 extra_gcd(b, a%b, y, x, d);
21 y -= (a/b) * x; 22 } 23 } 24 25 int main() 26 { 27 LL a, b, p, x, y, d; 28 scanf("%lld%lld%lld", &a, &b, &p); 29 extra_gcd(b, p, x, y, d); 30 x = (x + p) % p; 31 printf("%lld\n", (a * x) % p); 32 return 0; 33 }

題目的代碼

#include <iostream>
#include 
<string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> using namespace std; #define INF = 0x3f3f3f3f #define MST(vis,x) memset(vis,x,sizeof(vis)) #define ll long long #define maxn 100005 const ll mod=1e9+7; ll a[maxn]; ll b[maxn]; ll dp[maxn][2];//dp[x][0]代表相等,dp[x][1]代表大於 ll quickpow(ll x,ll y) { ll ans=1; while(y>0) { if(y&1)ans=ans*x%mod; x=x*x%mod; y/=2; } return ans; } int main() { ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF) { for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<=n;i++)scanf("%lld",&b[i]); MST(dp,0); dp[0][0]=1; ll all=0; for(int i=1;i<=n;i++) { if(a[i]==0)all++; if(b[i]==0)all++; if(a[i]&&b[i]) { if(a[i]==b[i]) { dp[i][0]=dp[i-1][0]; dp[i][1]=dp[i-1][1]; } else if(a[i]>b[i]) { dp[i][1]=(dp[i-1][1]+dp[i-1][0])%mod; dp[i][0]=0; } else { dp[i][1]=dp[i-1][1]; dp[i][0]=0; } } else if(a[i]==0&&b[i]==0) { dp[i][0]=dp[i-1][0]*m%mod; dp[i][1]=(dp[i-1][1]*(m*m%mod)%mod+dp[i-1][0]*((m*(m-1)/2)%mod)%mod)%mod; } else if(a[i]==0) { dp[i][0]=dp[i-1][0]%mod; dp[i][1]=(dp[i-1][1]*m%mod+dp[i-1][0]*(m-b[i])%mod)%mod; } else if(b[i]==0) { dp[i][0]=dp[i-1][0]%mod; dp[i][1]=(dp[i-1][1]*m%mod+dp[i-1][0]*(a[i]-1)%mod)%mod; } } cout << dp[n][1]*quickpow(quickpow(m,all),mod-2)%mod << endl; } return 0; }

codeforces 935D Fafa and Ancient Alphabet逆元加dp