hdu5407 CRB and Candies(數論-Kummer定理)
阿新 • • 發佈:2019-01-12
題意
求lcm(C(n,0),C(n,1),…,C(n,n)),n<=1e6
思路來源
https://blog.csdn.net/u010579068/article/details/47833525
https://www.zhihu.com/question/34859879(關於Kummer定理及其LCM性質的證明)
題解
關於lcm(C(n,0),C(n,1),…,C(n,n))=lcm(1,2,…,n,n+1)/(n+1)的證明見知乎的貼子,
看了兩天,沒有看懂,可謂是見過的最毒瘤的題,勒讓德定理部分還好,進位那裡就不明白了
就記結論吧,lcm(C(n,0),C(n,1),…,C(n,n))=lcm(1,…,n+1)/(n+1)
然後怎麼求lcm(1,…,n+1)呢,
如果一個數q是一個質因子p的k次方,說明這個數較前面的數來講,多了一個質因數p因子,因此lcm要乘以p
否則,這個數就能用之前的質因數表示,
篩出1-1e6的素數,然後對形如p^k形式的再篩一遍存到isprime[]表裡,令isprime[q]=p
如果isprime[q],lcm[n]=isprime[q]*lcm[n-1],
否則lcm[n]=lcm[n-1],
程式碼還是挺好寫的,主要是數論題的沙雕證明太難了啊……
程式碼
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const int INF=0x3f3f3f3f; const int maxn=1e6+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<int,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; ll jc[maxn],prime[maxn],isprime[maxn],cnt; bool ok[maxn]; void init() { for(ll i=2;i<maxn;++i) { if(ok[i])continue; prime[cnt++]=i; for(ll j=i*i;j<maxn;j+=i) ok[j]=1; } for(ll i=0;i<cnt;++i) { for(ll j=1;j<maxn;j*=prime[i]) { isprime[j]=prime[i]; } } jc[1]=1; for(ll i=2;i<maxn;++i) { if(isprime[i]) { jc[i]=jc[i-1]*isprime[i]; if(jc[i]>=mod)jc[i]%=mod; } else jc[i]=jc[i-1]; } } ll modpow(ll x,ll n,ll mod) { if(n==0)return 1; ll q=modpow(x,n/2,mod),res=q*q; if(res>=mod)res%=mod; if(n&1)res=res*x; if(res>=mod)res%=mod; return res; } int main() { init(); int t; sci(t); while(t--) { int n; sci(n); ll inv=modpow(n+1,mod-2,mod); printf("%lld\n",jc[n+1]*inv%mod); } return 0; }