T1
exgcd求逆元,化除为乘,因为除法不支持分配律;
时间 : O(log mod) ;
对于 (1/a) mod p;
求得a %p意义下 的逆元x,在模运算中可以替代1/a,相当于倒数(x并不一定等于倒数,只是
在取模的意义下与倒数发挥作用相同);
逆元为积性函数;
逆元x可能为负数,所以要 ( x%mod + mod ) % mod;
注意开long long;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll MAXN=300001,mod=1000000007;
ll inv,fac[MAXN],n,m,y,ans,t;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) {x=1,y=0;return;}
exgcd(b,a%b,x,y);
t=x,x=y,y=t-(a/b)*y;
return;
}
void solve()
{
scanf("%lld%lld",&n,&m);
fac[0]=1;
for(ll i=1;i<=n;i++) fac[i]=(fac[i-1] % mod * i % mod) % mod;
exgcd(fac[m],mod,inv,y);
inv=(inv % mod + mod) % mod;
ans=inv%mod;
inv=y=0;
exgcd(fac[n-m],mod,inv,y);
inv=(inv % mod + mod)% mod ;
ans=(ans * (inv %mod) ) %mod;
cout<<(fac[n] % mod * ans % mod) % mod;
return;
}
int main()
{
solve();
return 0;
}
费马小定理:
逆元利器;
假如p是质数, 且 gcd (a,p) = 1,那么 a ^ (p-1) ≡ 1(mod p)
则 a^(p-2)是 a%p意义下的逆元;
初始化;
注意 1的逆元为1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll MAXN=300001,mod=1000000007;
ll fac[MAXN],inv[MAXN],n,m;
ll ksm(ll a,ll b)
{
ll tot=1;
while(b)
{
if(b & 1) tot=(tot*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return tot%mod;
}
void solve()
{
cin>>n>>m;
fac[0]=1,inv[0]=1;
for(int i=1;i<=n;i++)
{
fac[i]=fac[i-1] * i %mod;
inv[i]=ksm(fac[i],mod-2)%mod;
}
cout<<(inv[m] %mod * inv[n-m] %mod * fac[n])%mod;
return;
}
int main()
{
solve();
return 0;
}
T2
调了一中午精度,最后也没调来,先弃了;
吐槽:
标程的状态转移不对;
题外话:
改了码风,好看了不少233;
思路:
dp[i][j]:前i个袋子中有j个袋子选到以1开头的球;
由于i只从i-1转移而来;
所以滚动数组优化;
注意:
用前缀和记录 以1打头的数,再计算;
第40行记录答案时,为了防止精度被卡,可以扩大后再枚举;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double ld;
const ll MAXN=2001;
ld dp[MAXN],p[MAXN],ans;
ll n,k;
ll getsum(ll num)
{
if(!num) return 0;
ll now = 1,sum = 1;
if(num < 10) return sum;
for(ll i = 1;i <= 19;i ++)
{
now *= 10;
if(now > num) return sum;
else if(now*2 > num) return num-now+sum+1;
sum+=now;
}
}
void solve()
{
scanf("%d%d",&n,&k);
dp[0]=1;
for(int i=1;i<=n;i++)
{
int l,r;
scanf("%d%d",&l,&r);
ld p=(ld)((ld)(getsum(r) - (ld)getsum(l - 1)) / (ld)(r - l + 1));
for(int j = i; ~j ;j --) dp[j] = dp[j-1] * p + dp[j] * (1 - p);
}
for(int i = n ; i *100>= n * k; i --) ans += (ld)dp[i];
printf("%.7f",ans);
return;
}
int main()
{
solve();
return 0;
}
T3
暂时弃掉~;