BZOJ 5323: [Jxoi2018]游戏 组合

code:

#include <cstdio> 
#include <algorithm> 
#define ll long long 
#define M 1000006 
#define N 10000002   
#define mod 1000000007    
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
bool vis[N];  
int fac[N],prime[M],inv[N],tot,n,T;   
int qpow(int x,int y) 
{
    int tmp=1; 
    for(;y;y>>=1,x=(ll)x*x%mod) 
        if(y&1) tmp=(ll)tmp*x%mod; 
    return tmp;   
}    
void Init(int L,int R) 
{    
    int i,j; 
    for(i=2;i<=R;++i) 
    {
        if(!vis[i]) 
        {
            prime[++tot]=i;     
            if(1<L&&i>=L) ++T;  
        }
        for(j=1;j<=tot&&prime[j]*i<=R;++j) 
        {
            vis[i*prime[j]]=1;          
            if(prime[j]<L&&i<L&&prime[j]*i>=L) ++T;  
            if(i%prime[j]==0) break;   
        }   
    }   
    if(L==1) T=1;    
    fac[0]=1;  
    for(i=1;i<=R;++i) fac[i]=(ll)fac[i-1]*i%mod; 
    inv[R]=qpow(fac[R],mod-2);   
    for(i=R;i;--i) inv[i-1]=(ll)inv[i]*i%mod;         
}
int C(int x,int y) 
{
    if(x<0||y<0||x<y) return 0;  
    return (ll)fac[x]*inv[y]%mod*inv[x-y]%mod;   
}
int main() 
{ 
    // setIO("input"); 
    int i,j,l,r;   
    scanf("%d%d",&l,&r),n=r-l+1;  
    Init(l,r); 
    int ans=0;    
    for(i=T;i<=n;++i) 
    {
        int tmp=(ll)C(n-T,n-i)*fac[n-i]%mod*fac[i-1]%mod*T%mod;      
        ans=(ll)(ans+(ll)tmp*i%mod)%mod;    
    }
    printf("%d\n",ans);   
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12244630.html