「JXOI2018」游戏

    注意输出的应该是 所有方案的和,,而不是期望。

    我们不妨把依赖关系建图,可以发现 所有没有入度的点都被查水表了一次 是 游戏结束的 充要条件。

    于是我们只需要知道有多少没有入度的点,然后再排列算一算就ojbk了。

     前者是一个数论问题,我们贪心的把一个数/他的最小质因子,如果<L就说明它没有入度。。(1除外)

    后者就是一个基本的排列计数把23333

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7,ha=1e9+7;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline int ksm(int x,int y){ int an=1; for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha; return an;}
int zs[maxn/10],t=0,low[maxn+5],ans;
int L,R,N,jc[maxn+5],ni[maxn+5],n;
bool v[maxn+5];
inline int P(int x,int y){ return x<y?0:jc[x]*(ll)ni[x-y]%ha;}

inline void init(){
	low[1]=233;
	for(int i=2;i<=R;i++){
		if(!v[i]) zs[++t]=i,low[i]=i;
		for(int j=1,u;j<=t&&(u=zs[j]*i)<=R;j++){
			v[u]=1,low[u]=zs[j];
			if(!(i%zs[j])) break;
		}
	}
	
	jc[0]=1;
	for(int i=1;i<=N;i++) jc[i]=jc[i-1]*(ll)i%ha;
	ni[N]=ksm(jc[N],ha-2);
	for(int i=N;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
}

inline void solve(){
	for(int i=L;i<=R;i++) if(i/low[i]<L) n++;
	ans=N*(ll)P(N,n)%ha*(ll)jc[N-n]%ha;
	for(int i=N-1;i>=n;i--) ans=add(ans,ha-P(i,n)*(ll)jc[N-n]%ha);
}

int main(){
	scanf("%d%d",&L,&R),N=R-L+1,init();
	solve(),printf("%d\n",ans);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/JYYHH/p/9007587.html