bzoj 2186: [Sdoi2008]沙拉公主的困惑
Submit:?2463??Solved:?820
[Submit][Status][Discuss]
Description
大富翁國(guó)因?yàn)橥ㄘ浥蛎?#xff0c;以及假鈔泛濫,政府決定推出一項(xiàng)新的政策:現(xiàn)有鈔票編號(hào)范圍為1到N的階乘,但是,政府只發(fā)行編號(hào)與M!互質(zhì)的鈔票。房地產(chǎn)第一大戶沙拉公主決定預(yù)測(cè)一下大富翁國(guó)現(xiàn)在所有真鈔票的數(shù)量。現(xiàn)在,請(qǐng)你幫助沙拉公主解決這個(gè)問題,由于可能張數(shù)非常大,你只需計(jì)算出對(duì)R取模后的答案即可。R是一個(gè)質(zhì)數(shù)。
Input
第一行為兩個(gè)整數(shù)T,R。R<=10^9+10,T<=10000,表示該組中測(cè)試數(shù)據(jù)數(shù)目,R為模后面T行,每行一對(duì)整數(shù)N,M,見題目描述 m<=n
Output
共T行,對(duì)于每一對(duì)N,M,輸出1至N!中與M!素質(zhì)的數(shù)的數(shù)量對(duì)R取模后的值
Sample Input
1 114 2
Sample Output
1數(shù)據(jù)范圍:
對(duì)于100%的數(shù)據(jù),1 < = N , M < = 10000000
題解: 這題要求在(1,N!)里與M!互質(zhì)的數(shù)的個(gè)數(shù),由于N!>M!,所以答案分成兩部分,一部分是用歐拉函數(shù)phi(M!),表示1~M!里與M!互質(zhì)的數(shù)的個(gè)數(shù),還有一部分是(M!+1,N!)里的一部分?jǐn)?shù)也有可能和M!互質(zhì)。但是這部分?jǐn)?shù)字比較難處理,現(xiàn)在由輾轉(zhuǎn)相除法的原理可知:如果gcd(x,M!)==1,則一定有g(shù)cd(x+M!,M!)==1,所以(M!+1,N!)里的和M!互質(zhì)的數(shù)一定是x+kM! (k∈Z)。所以答案就是:phi(M!)*(N!/M!)%R 現(xiàn)在的問題就是N!,M!都很大,如何求上面的式子。我們讓N!%R單獨(dú)算,把phi(M!)/(M!)放在一起,令f(M)=phi(M!)/M!,根據(jù)phi(x)=x*(1-1/p1)*(1-1/p2)*…*(1-1/pk) ,可以上下同時(shí)消掉M!,f(m)=(p1-1)/p1*(p2-1)/p2*…其中pi為不大于M的質(zhì)數(shù)(因?yàn)橛蓺W拉函數(shù)知pi是素因子,而M!=1*2*3*4***M,所以小于M的素?cái)?shù)就是素因子),所以對(duì)于f(i),如果i是質(zhì)數(shù)f(i)=f(i-1)*(i-1)/i,否則f(i)=f(i-1)。 還有一個(gè)問題,就是f(i)=f(i-1)*(i-1)/i 在模R意義下存在除法,這就有可能出現(xiàn)分?jǐn)?shù),這就需要用到乘法逆元,把除法轉(zhuǎn)化成乘法。具體講解:乘法逆元?用擴(kuò)展歐幾里得求解乘法逆元
根據(jù)以上關(guān)系式可以預(yù)處理f(1)~f(10^7)。每次詢問只需要輸出f(M)*N!%R即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn=1e7+5; 5 int N,M,P,T; 6 LL fac[maxn],ans[maxn]; 7 bool f[maxn]; 8 inline void exgcd(int a,int b,int &x,int &y){ 9 if(b==0){ 10 x=1; y=0; 11 return ; 12 } 13 exgcd(b,a%b,x,y); 14 int t=x; 15 x=y; y=t-a/b*x; 16 } 17 inline int getinv(int a){ 18 int x=0,y=0; 19 exgcd(a,P,x,y); 20 return (x%P+P)%P; 21 } 22 int main(){ 23 scanf("%d%d",&T,&P); 24 fac[1]=1; 25 for(int i=2;i<=1e7;i++) fac[i]=fac[i-1]*i%P;//預(yù)處理 N!%R 26 ans[1]=1; 27 for(int i=2;i<=1e7;i++){ 28 if(f[i]==false){// 是素?cái)?shù) 29 ans[i]=ans[i-1]*(i-1)%P*getinv(i)%P; 30 for(int j=2;j<=1e7/i;j++) f[i*j]=true;//篩素?cái)?shù) 31 } 32 else ans[i]=ans[i-1]; 33 } 34 while(T--){ 35 scanf("%d%d",&N,&M); 36 printf("%lld\n",ans[M]*fac[N]%P); 37 } 38 return 0; 39 }?
轉(zhuǎn)載于:https://www.cnblogs.com/CXCXCXC/p/5222291.html
總結(jié)
以上是生活随笔為你收集整理的bzoj 2186: [Sdoi2008]沙拉公主的困惑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6、JavaScript进阶篇③——浏览
- 下一篇: ZOJ1027 Travelling F