• Longge's problem ( gcd的积性)


    Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.

    "Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
    Input
    Input contain several test case.
    A number N per line.
    Output
    For each N, output ,∑gcd(i, N) 1<=i <=N, a line
    Sample Input
    2
    6
    Sample Output
    3
    15




    这题推完柿子 之后,直接根号枚举因子,然后算phi 也能过....
    但是这题想考的是gcd是一个积性函数

    gcd(i*j,n)=gcd(i,n)*gcd(j,n)

    好了现在我们需要来学习真正的姿势了,我也是刚学的,利用gcd是积性函数的性质,根据前文说的,我们有这样的结论:n>1时 n=p1^a1*p2^a2*...*ps^as,p为n的质因子,那么f(n)是积性函数的充要条件是f(1)=1,及f(n) = f(p1^a1)*f(p2^a2)*...f(pr^ar),所以只要求f(pi^ai)就好。现在来看具体做法。

    f(pi^ai) =  Φ(pi^ai)+pi*Φ(pi^(ai-1))+pi^2*Φ(pi^(ai-2))+...+pi^(ai-1)* Φ(pi)+ pi^ai *Φ(1)

    根据性质1,我们可以做出如下化简

    f(pi^ai)=[pi^(ai-1)*(pi-1) ] +  [pi*pi^(ai-2)*(pi-1)]  +  [pi^2*pi^(ai-3)*(pi-1)]  +  [pi^3*pi^(ai-4)*(pi-1)]....[pi^(ai-1)*pi^(ai-ai)*(pi-1)]+pi^ai   ①

    然后对①提取公因子(pi-1)

    f(pi^ai)=(pi-1){[pi^(ai-1) ] +  [pi*pi^(ai-2)]  +  [pi^2*pi^(ai-3)]  +  [pi^3*pi^(ai-4)]....[pi^(ai-1)*pi^(ai-ai)]+[pi^ai/(pi-1)]}  ②

    紧接着我们发现出了最后一项每个[]每个方括号内乘积都等于pi^(ai-1),所以对②提取公因子pi^(ai-1)

    f(pi^ai)=(pi-1)*pi^(ai-1)*{ai+[pi/(pi-1)]} ③

    然后把(pi-1)/pi放进括号里得

    f(pi^ai)=pi^(ai)*{1+ai*(pi-1)/pi} ④

    这个 ④是单个f(pi^ai)的公式,我们提取所有的pi^(ai)相乘实际上就是n了,所以我们可以得到f(n)的公式:f(n)=n*∏(1+ai*(pi-1)/pi)

    然后我们看代码吧!









     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #ifdef WIN32
     5 #define LLD "%I64d"
     6 #else
     7 #define LLD "%lld"
     8 #endif
     9 #define ll long long
    10 using namespace std;
    11 ll n;
    12 inline int phi(int x){
    13     int ans=x;
    14     for(int i=2;1ll*i*i<=1ll*x;i++){
    15         if(x%i==0) {
    16             ans=ans/i*(i-1);
    17             while(x%i==0) x/=i;
    18         }
    19     }
    20     if(x>1) ans=ans/x*(x-1);
    21     return ans;
    22 }
    23 int main(){
    24 //     freopen("poj2480.in","r",stdin);
    25      while(scanf(LLD,&n)!=EOF){
    26          ll ans=0;
    27          for(int i=1;1ll*i*i<=1ll*n;i++){
    28             if(n%i==0){
    29                 int x=phi(n/i);ans+=1ll*x*i;
    30                 if(i*i!=n) {
    31                     int y=phi(i);ans+=1ll*y*(n/i);
    32                 }     
    33             }
    34          }
    35         printf(LLD"
    ",ans);
    36     }
    37     return 0;
    38 }

     

     

     

     














  • 相关阅读:
    WTM
    Spring Cloud
    Dapper
    Linux 常用命令
    JsonNetResult
    百度 副文本编译器
    GIT使用—一些概念
    GIT使用—创建一个版本库
    GIT使用—安装配置及工作流程
    灰度发布
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11053817.html
Copyright © 2020-2023  润新知