codeforces 711E 勒让德定理 逆元

要先化简再取模
公式很好推主要是化简
用到两条性质
1. gcd(2^n - k, 2^n) = gcd(k, 2 ^ n)
因为当k为奇数 2^n - k 为奇数 那等式两边都为1
当k为偶数时 2^n - k 为偶数 k = b * 2^k1 b为奇数 2^n - k = 2^k1*(2^(n-k1)-b) 2^(n-k1)-b 是奇数,所以gcd(2^n - k, 2^n) = gcd(k, 2 ^ n) = 2^k1
2. 勒让德定理
在正数n!的素因子标准分解式中,素数p的指数记作Lp(n!), 则
Lp(n!)=∑k≥1⌊n/p^k⌋ (n >= p^k)
然后最后gcd(2^t)也有了公式也有了就逆元加快速幂就能做了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define LL unsigned long long
#define mod 1000003ll
LL fastMod(LL a, LL n)
{
    LL ans = 1;
    while(n)
    {
        if(n & 1ll) ans *= a;
        a *= a;
        ans %= mod;
        a %= mod;
        n >>= 1ll;
    }
    return ans;
}
LL n, k;
int main()
{
    scanf("%I64u %I64u", &n, &k);
    if(n <= 63)
    {
        LL pre = 1;
        for(int i = 1; i <= n; i++) pre *= 2;
        if(pre < k)
        {
            printf("1 1\n");
            return 0;
        }
    }
    LL cnt = 0;
    for(LL i = 2; i <= (k - 1); i<<=1ll) cnt += (k - 1) / i;
    LL gcd = fastMod(2ll, cnt);
    LL ans1 = 1, ans2 = fastMod(2ll, n);
    for(LL i = 2; i <= k; i++)
    {
        ans1 *= ((ans2 - i + 1) % mod + mod) % mod;
        ans1 %= mod;
        if(ans1 == 0) break;
    }
    ans2 = fastMod(ans2, k -  1) % mod;
    ans1 = ans1 * fastMod(gcd, mod - 2) % mod;
    ans2 = ans2 * fastMod(gcd, mod - 2) % mod;
    ans1 = (ans2 - ans1 + mod) % mod;
    printf("%I64u %I64u\n", ans1, ans2);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值