题意:一年有s=2^n天,有k个人 问至少有两个人生日在同一天的概率?(答案%mod)
n,k<=1e18
算对立事件 任意两人生日都不同的概率 ( (2^n-1)*(2^n-2)*...*(2^n-(k-1)) ) /(2^(n*(k-1))
n,k<=1e18都非常大,尝试将分子分母同时约去gcd(A,B),分母是2的幂次 则gcd也肯定为2^i,找到最大i
分子可以展开成A=f(p)*2^n+(k-1)! f(p)为某个多项式
则gcd2^i满足2^i|2^n && 2^i|(k-1)! 根据Legendre's定理(其实就是算因子2在k!中出现多少次) 求出d=2^i
对于分母 可以直接消掉d 对于分子(2^n-1)*(2^n-2)*...*(2^n-(k-1))
若k>mod 则分子显然为0(因为分子为mod个连续的数相乘,至少有一个数为mod的倍数)
若k<mod mod=1e6+3 暴力算出分子后乘上逆元即可.总的复杂度为O(mod+log(k)+log(n))
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=2e5+20;
const ll mod=1e6+3;
ll n,k;
ll powmod(ll x,ll n)
{
ll s=1;
while(n)
{
if(n&1)
s=(s*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return s;
}
ll inverse(ll x)
{
return powmod(x,mod-2);
}
int main()
{
while(cin>>n>>k)
{
ll pw=0,d;
if(n<=63 && k>(1ll<<n))
{
puts("1 1");
continue;
}
ll A=1,B;
//if(k-1>=mod)
// A=0;
ll x=2;
//ÕÒµ½·Ö×ӺͷÖĸµÄgcd
while(x<=k-1)
pw+=(k-1)/x,x=x*2ll;
d=powmod(2ll,pw);
ll res=1,y=powmod(2,n);
for(ll i=1;i<=k-1;i++)
{
res=(res*(y-i+mod)%mod)%mod;
if(res==0)//×î¶à×ömod-1´Î
break;
}
res=(res*inverse(d))%mod;
A=res;
B=powmod(2ll,n)%mod;
B=powmod(B,k-1)%mod;
B=(B*inverse(d))%mod;
A=(B-A+mod)%mod;
cout<<A<<' '<<B<<endl;
}
return 0;
}