首先是求概率,考虑第一个人的生日是1,第二个人与第一个人不同的概率是1*(2^n-1/2^n)可以得出有k个人时不同的概率是P=A(2^n,k)/2^(n*k),相同的概率是1-P;
先考虑展P的展开得到分子=(2^n-1)(2^n-2)..(2^n-k+1),分母为2^(n-1)*k,因为当k>=MOD时分子整除MOD所以只需要求分母乘上gcd(分子,分母)的逆元后的数值,当k<MOD时分子分母需要同时乘上gcd(分子,分母)的逆元.
之后问题就转化为如何求gcd了,当k<MOD时可以通过暴力。
当k>=MOD时可以通过勒让德定理(Lr(n!)=sum[n/2^p])求得
之后便是注意当k>2^n时,由于抽屉原理,要输出1 1
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
using namespace std;
#define ll long long
#define F(x,a,b) for (ll x=a;x<=b;x++)
#define MOD 1000003
ll _fast(ll k){
if (k==0) return 1;if (k&1){return _fast(k-1)*2%MOD;}
else {ll t=_fast(k/2);return t*t%MOD;}
}
bool jud(ll n,ll k){
ll t=1;
while(n)
{
t*=2;
if (t>=k) return 0;
n--;
}
return 1;
}
int main()
{
ll n,k;
cin>>n>>k;
ll N=_fast(n);
if (jud(n,k)) {printf("1 1");return 0;}
if (k<MOD)
{
ll cnt=0;
F(i,1,k-1)
{
ll t=i;
while ((t&1)==0)
{
t=t>>1;
cnt++;
}
}
ll gcd=MOD-cnt-1;
ll ans=1;
F(i,1,k-1)
{
ans=ans*(N-i+MOD)%MOD;
}
ans=ans*_fast(gcd)%MOD;
ll mo=_fast(n%(MOD-1)*(k-1)%(MOD-1))*_fast(gcd)%MOD;
cout<<(mo-ans+MOD)%MOD<<" "<<mo<<endl;
}
else
{
ll t=2;ll cnt2=0;
while (t<=k-1)
{
cnt2+=(k-1)/t;
t=t*2;
}
ll gcd=MOD-cnt2%(MOD-1)-1;
ll xx=n%(MOD-1)*((k-1)%(MOD-1));
ll mo=_fast(xx)%MOD*(_fast(gcd)%MOD)%MOD;
cout<<mo<<" "<<mo<<endl;
}
}