要先化简再取模
公式很好推主要是化简
用到两条性质
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;
}