【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)

【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)

题面

BZOJ
洛谷

题解

显然要考虑的位置只有那些在\([l,r]\)中不存在任意一个约数的数。
假设这样的数有\(x\)个,那么剩下的数有\(n-x\)个。
枚举时间\(t\),那么强制在\(t\)时刻放下\(x\)数中的最后一个,
那么这样子的方案数就是\(\displaystyle {t-1\choose x-1}*x!*(n-x)!\)
预处理阶乘和逆元就很好做了。

#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 1000000007
#define MAX 10000001
bool vis[MAX];
int jc[MAX],jv[MAX],l,r,n,x,ans;
int main()
{
	scanf("%d%d",&l,&r);n=r-l+1;
	for(int i=l;i<=r;++i)
		if(!vis[i]){++x;for(int j=i;j<=r;j+=i)vis[j]=true;}
	jc[0]=jv[0]=jv[1]=1;
	for(int i=2;i<=n;++i)jv[i]=1ll*jv[MOD%i]*(MOD-MOD/i)%MOD;
	for(int i=1;i<=n;++i)jc[i]=1ll*jc[i-1]*i%MOD;
	for(int i=1;i<=n;++i)jv[i]=1ll*jv[i-1]*jv[i]%MOD;
	for(int i=x;i<=n;++i)ans=(ans+1ll*jc[i]%MOD*jv[i-x])%MOD;
	ans=1ll*ans*x%MOD*jc[n-x]%MOD;printf("%d\n",ans);
	return 0;
}
posted @ 2019-02-23 15:12  小蒟蒻yyb  阅读(304)  评论(0编辑  收藏  举报