zoukankan      html  css  js  c++  java
  • POJ 2480 求每一个数对于n的最大公约数的和

    这里是枚举每一个最大公约数p,那么最后求的是f(n) = sigma(p*phi(n/p))    phi()为欧拉函数

    这里可以试着算一下,然后会发现这个是积性函数的

    那么只要考虑每一类质数分开算,最后乘在一起就行了

    而对于f(p^k) p为素数的求解可以这样考虑

    对于前一个f(p^(k-1)) , 那么f(p^k)相当于把f(p^(k-1)) 中的所有情况都乘上了p ,  然后加上新产生的gcd()=1的情况,这个利用过程中的欧拉函数定理求解

    phi(n) = (p1-1)*p1^(k1-1)....+(pn-1)*pn^(kn-1)

    这里只能在只含有唯一素数因子的情况下计算,因为如果有别的素数因子,新产生的gcd除了1以外,还有当前乘上的因子p之外的素数因子考虑不到,会使答案变小,

    这里大概想想就可以知道了

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <cstdlib>
     7 using namespace std;
     8 #define ll long long
     9 #define N 100000
    10 int prime[N+5] , tot , fai[N+5];
    11 bool check[N+5];
    12 
    13 void get_prime()
    14 {
    15     for(int i=2 ; i<=N ; i++){
    16         if(!check[i]){
    17             prime[tot++] = i;
    18             fai[i] = i-1;
    19         }
    20         for(int j=0 ; j<tot ; j++){
    21             if((ll)prime[j]*i>N) break;
    22             check[prime[j]*i] = true;
    23             if(i%prime[j]==0){
    24                 fai[i*prime[j]] = fai[i]*prime[j];
    25                 break;
    26             }else fai[i*prime[j]] = fai[i]*(prime[j]-1);
    27         }
    28     }
    29 }
    30 
    31 void solve(int n)
    32 {
    33     /*这里求出一个gcd(i,n)=1的个数,就是求n的欧拉函数phi(n)
    34     phi(n) = (p1-1)*p1^(k1-1)....+(pn-1)*pn^(kn-1)
    35     */
    36     ll ret = 1;
    37     for(int i=0 ; i<tot ; i++){
    38         if(prime[i]>n) break;
    39         int cnt = 0;
    40         ll phi = 0 , tmp = 1;
    41         while(n%prime[i]==0){
    42             if(!cnt) phi = prime[i]-1;
    43             else phi = phi*prime[i];
    44             tmp = tmp*prime[i]+phi;
    45             cnt++;
    46             n/=prime[i];
    47         }
    48         ret = ret*tmp;
    49     }
    50     if(n>1){
    51         ret = ret*(2*(ll)n-1); //这里的n可能是超过1e9的整数,*2有可能超int,要注意
    52        // if(ret<0) cout<<"last "<<n<<" "<<(2*n-1)<<" "<<ret<<endl;
    53     }
    54     printf("%I64d
    " , ret);
    55 }
    56 int main() {
    57    // freopen("a.in" , "r" , stdin);
    58    // freopen("out.txt" , "w" , stdout);
    59     get_prime();
    60     int n;
    61     while(~scanf("%d" , &n)){
    62         solve(n);
    63     }
    64 }
  • 相关阅读:
    STM32F030 启用内部晶振并配置系统时钟为48M
    CSS 动画过程及间接实现样式延时
    Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data
    21 GetHashCode Equels ReferenceEquals的比较
    3 Base64编码主要应用在那些场合?
    2 什么是编码?什么是Unicode?
    2 名企面试_02
    ListView
    Image
    Container
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4798977.html
Copyright © 2011-2022 走看看