hdu5407CRB and Candies 求逆元

//求LCM(C(n,0),C(n,1),C(n,2),...,C(n,n))
//令an=LCM(C(n,0),C(n,1),C(n,2),...,C(n,n))
//b[n]=LCM(1,2,3,...,n)
//a[n]=(b[n]+1)/n+1
//if (n=p^k)bn=p*(b[n−1]) else b[n]=b[n−1]
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1e6+10 ;
typedef long long ll ;
const ll mod = 1e9+7 ;
ll b[maxn] , a[maxn] ;
int p[maxn] ;
int prime[maxn] ;
void get_prime()
{
    memset(prime , 0 , sizeof(prime)) ;
    memset(p , 0 , sizeof(p)) ;
    for(int i = 2;i < maxn;i++)
    {
        if(prime[i])continue ;
        for(int j = i*2;j < maxn ;j += i)
        prime[j] = 1 ;
    }
    for(int i = 2;i < maxn ;i++)
    {
        if(prime[i])continue ;
        p[i] = i ;
        for(ll j = i ;j < maxn ;j *= (ll)i)
        p[j] = i ;
    }
}
ll exgcd(ll a , ll b , ll &x , ll &y)
{
    if(b == 0)
    {
        x = 1 ;
        y = 0 ;
        return a ;
    }
    ll r = exgcd(b , a%b , x , y) ;
    ll temp = x ;
    x = y ;
    y = temp - a/b*y ;
    return r ;
}
int main()
{
    int t ;
    scanf("%d" , &t) ;
    get_prime() ;
    while(t--)
    {
        int n ;
        scanf("%d" , &n) ;
        ll x , y = 0;
        exgcd(n+1 , mod , x , y) ;
        x = (x%mod + mod)%mod ;
        b[1] = 1 ;
        for(int i = 2;i <= n+1;i++)
        if(p[i])
        b[i] = (b[i-1]*(ll)p[i])%mod ;
        else b[i] = b[i-1] ;
        printf("%lld\n" ,(b[n+1]*x)%mod) ;
    }
    return  0 ;
}

你可能感兴趣的:(hdu5407CRB and Candies 求逆元)