qbxt Day 2 数论 +DP +DP

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

这里写图片描述

暂时弃掉~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值