显然上下块可以整除,对上下块经行质因子分解,最终枚举计算质数幂次差即可。分解的时候其实用最小质因子迭代会更快。
int prime[5001000],minprime[5001000];
void euler(int n) //欧拉筛
{
minprime[1]=1;
int c=0,i,j;
for(i=2; i<=n; i++)
{
if(!minprime[i])
prime[++c]=i,minprime[i]=i;
for(j=1; j<=c&&i*prime[j]<=n; j++)
{
minprime[i*prime[j]]=prime[j];
if(i%prime[j]==0)
break;
}
}
}
ll vis[2000100];
ll vis_[2001000];
const int rnm=1e9;
ll fuck[12];
ll op=0;
signed main()
{
euler(2500000);
ll x,y;
read(x);
read(y);
ll n,m;
n=x;
m=y;
if(n<m)
{
printf("0");
return 0;
}
for(int i=1; i<=n; i++)
{
ll ok=i;
ll f=0;
if(i<=m)
{
f++;
}
if(i<=n-m)
{
f++;
}
for(int j=1; prime[j]*prime[j]<=ok; j++)
{
if(ok%prime[j]==0)
{
ll x=0;
while(ok%prime[j]==0)
{
x++;
ok/=prime[j];
}
vis[prime[j]]+=x;;
vis_[prime[j]]+=f*x;
}
}
if(ok>1)
{
vis[ok]++;
vis_[ok]+=f;
}
}
ll add=1;
for(int i=1; prime[i]<=n; i++)
{
add=(add%rnm*qp(prime[i],(vis[prime[i]]-vis_[prime[i]]),rnm))%rnm;
}
printf("%lld",add%rnm);
}