「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; }