codeforces 711E 勒让德定理 逆元

来源:互联网 发布:释放内存软件 编辑:程序博客网 时间:2024/06/05 23:49

要先化简再取模
公式很好推主要是化简
用到两条性质
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 1000003llLL 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;}
0 0
原创粉丝点击