Bi-shoe and Phi-shoe (歐拉函數)
阿新 • • 發佈:2019-02-11
cout scan 第一個 cor 歐拉 利用 -s 積性函數 color
特殊性質:當n為質數時,
, 證明與上述類似。
若n為質數則
如:
ψ(10)=10×(1-1/2)×(1-1/5)=4;
ψ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;
ψ(49)=49×(1-1/7)= =42。
題目描述:
題目大意:一個竹竿長度為p,它的score值就是比p長度小且與且與p互質的數字總數,比如9有1,2,4,5,7,8這六個數那它的score就是6。給你T組數據,每組n個學生,每個學生都有一個幸運數字,求出要求買n個竹子每個竹子的score都要大於或等於該學生的幸運數字,每個竹竿長度就是花費,求最小花費。
首先弄清歐拉函數的定義,詳見:https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0/1944850?fr=aladdin
函數內容 通式: 其中p1, p2……pn為x的所有質因數,x是不為0的整數。 φ(1)=1(和1互質的數(小於等於1)就是1本身)。 歐拉函數是積性函數——若m,n互質,利用歐拉函數和它本身不同質因數的關系,用篩選計算出某個範圍內所有數的歐拉函數值。
/* 特性 : 1.若a為質數,phi[a]=a-1; 2.若a為質數,b mod a=0,phi[a*b]=phi[b]*a 3.若a,b互質,phi[a*b]=phi[a]*phi[b](當a為質數時,if b mod a!=0 ,phi[a*b]=phi[a]*phi[b]) */ int m[n],phi[n],p[n],nump; //m[i]標記i是否為素數,0為素數,1不為素數;p是存放素數的數組;nump是當前素數個數;phi[i]為歐拉函數 int make() { phi[1]=1; for (int i=2;i<=n;i++) { if (!m[i])//i為素數 { p[++nump]=i;//將i加入素數數組p中 phi[i]=i-1;//因為i是素數,由特性得知 } for (int j=1;j<=nump&&p[j]*i<n;j++) //用當前已的到的素數數組p篩,篩去p[j]*i { m[p[j]*i]=1;//可以確定i*p[j]不是素數 if (i%p[j]==0) //看p[j]是否是i的約數,因為素數p[j],等於判斷i和p[j]是否互質 { phi[p[j]*i]=phi[i]*p[j]; //特性2 break; } else phi[p[j]*i]=phi[i]*(p[j]-1); //互質,特性3其,p[j]-1就是phi[p[j]] } } }
現用另一種思路求任意一個數N,求出ψ(N),詳見轉載博客:https://blog.csdn.net/leolin_/article/details/6642096
代碼實現:
1 #include<stdio.h> //歐拉之實現 2 int ef(int n) 3 { 4 int cnt=n; 5 int i; 6 for(i=2;i<=n;i++) 7 if(n%i==0) 8 { 9 cnt - =cnt/i; // m-m/p 10 while(n%i==0) 11 n/=i; 12 } 13 return cnt; 14 } 15 int main() 16 { 17 int n;int m; 18 int count; 19 while(scanf("%d",&m)!=EOF) 20 { 21 22 while(m--){ 23 scanf("%d",&n); 24 count=ef(n); 25 printf("%d\n",count);} 26 } 27 return 0; 28 }
看完上面的內容,我們就知道一根長度為p的竹竿它的score其實就是歐拉函數值φ(p)。又因為一個素數p的φ(p)=p-1,所以我們只需要從x+1(x是幸運數字)開始找第一個出現的素數,那就是最小花費。
代碼實現:
1 #include<iostream> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e7+5; 5 6 bool prime[N]; 7 8 void is_prime(){ 9 for(int i=2;i<N;i++){ 10 prime[i]=true; 11 } 12 for(int i=2;i*i<N;i++){ 13 if(prime[i]){ 14 for(int j=i*i;j<=N;j+=i){ 15 prime[j]=false; 16 } 17 } 18 } 19 } 20 21 int main(){ 22 is_prime(); 23 int t,n; 24 cin>>t; 25 for(int i=1;i<=t;i++){ 26 cin>>n; 27 ll sum=0; 28 for(int j=1;j<=n;j++){ 29 int x; 30 cin>>x; 31 for(int k=x+1;;k++){ 32 if(prime[k]){ 33 sum+=k; 34 break; 35 } 36 } 37 } 38 cout<<"Case "<<i<<": "<<sum<<" Xukha"<<endl; 39 } 40 }
Bi-shoe and Phi-shoe (歐拉函數)