1. 程式人生 > >【BZOJ2186】【SDOI2008】沙拉公主的困惑

【BZOJ2186】【SDOI2008】沙拉公主的困惑

str 可能 bzoj2186 -c oid line 存在 div gcd

啥都不會只能學數論QAQ

原題:

大富翁國因為通貨膨脹,以及假鈔泛濫,政府決定推出一項新的政策:現有鈔票編號範圍為1到N的階乘,但是,政府只發行編號與M!互質的鈔票。房地產第一大戶沙拉公主決定預測一下大富翁國現在所有真鈔票的數量。現在,請你幫助沙拉公主解決這個問題,由於可能張數非常大,你只需計算出對R取模後的答案即可。R是一個質數。

1<=M<=N<=10000000

恩,歐拉函數推推推,無果,gg看題解

首先如果gcd(x,y)=1,那麽gcd(x+y,y)=1,gcd(x+2y,y)=1

那麽如果x跟m!互質,x+m!與m互質,x+2*m!也與m互質

因為m<=n所以n一定是m的倍數,所以對於每個x<=m!且與m!互質,都存在(n!)/(m!)個x也與m!互質

那麽答案就是phi(m)*(n!)/(m!)

因為m!的質因子剛好是<=m的所有質數,所以根據歐拉函數的通式,phi(m!)=(m!)*π((pi-1)/pi) (pi<=m)

把phi代進去答案就變成了(n!)*π((pi-1)/pi) (pi<=m)

因為n,m都<=1e7所以把質數,n!,pi的逆元預處理出來就可以把π((pi-1)/pi)頁預處理出來

對於每次詢問直接計算即可

線篩逆元似乎挺有用的

什麽都不會數論只能看題解怎麽辦啊QAQ

代碼:

技術分享
 1 #include<bitset>
 2 #include<cstdio>
 3 #include<cstring>
 4
#include<iostream> 5 #include<algorithm> 6 #define M 10000001 7 using namespace std; 8 typedef long long ll; 9 bool not_prime[M+100]; 10 ll prime[500500],ans[M+100],fac[M+100],rev[M+100]; 11 int n,m,p,T,tot; 12 void Linear_Shaker() 13 { 14 ll i,j; 15 for(i=2;i<=M;i++) 16 { 17 if
(!not_prime[i]) 18 prime[++tot]=i; 19 for(j=1;j<=tot&&prime[j]*i<=M;j++) 20 { 21 not_prime[prime[j]*i]=1; 22 if(i%prime[j]==0) 23 break; 24 } 25 } 26 fac[1]=1; 27 for(i=2;i<=M;i++) 28 fac[i]=fac[i-1]*i%p; 29 rev[1]=1; 30 for(i=2;i<=M&&i<p;i++) 31 rev[i]=(p-p/i)*rev[p%i]%p; 32 ans[1]=1; 33 for(i=2;i<=M;i++) 34 { 35 if(!not_prime[i]) 36 ans[i]=ans[i-1]*(i-1)%p*rev[i%p]%p; 37 else 38 ans[i]=ans[i-1]; 39 } 40 } 41 int main() 42 {freopen("ddd.in","r",stdin); 43 scanf("%d%d",&T,&p); 44 Linear_Shaker(); 45 for(int i=1;i<=T;++i) 46 { 47 scanf("%d%d",&n,&m); 48 printf("%d\n",fac[n]*ans[m]%p); 49 } 50 }
View Code

【BZOJ2186】【SDOI2008】沙拉公主的困惑