zoukankan      html  css  js  c++  java
  • 【BZOJ】【2705】【SDOI2012】Longge的问题

    欧拉函数/狄利克雷卷积/积性函数


      

    2705: [SDOI2012]Longge的问题

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 1275  Solved: 820
    [Submit][Status][Discuss]

    Description

    Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

    Input

    一个整数,为N。

    Output

    一个整数,为所求的答案。

    Sample Input

    6

    Sample Output

    15

    HINT

    【数据范围】

    对于60%的数据,0<N<=2^16。

    对于100%的数据,0<N<=2^32。

     

    Source

    [Submit][Status][Discuss]

      掉到莫比乌斯反演的坑里无法自拔,问了zyf&在网上看了题解才做出来TAT……我果然好弱

      这个题是要求$sum_{x=1}^{n}gcd(x,n)$,考虑它的实际意义,我们可以得到$ans=sum_{i|n}i*varphi(frac{n}{i})$

      但是明显φ函数我们是没法预处理的……($frac{n}{i}$这玩意太大了),但考虑到n的约数不会太多,所以我们可以边找因数边计算φ。

     1 /**************************************************************
     2     Problem: 2705
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:16 ms
     7     Memory:804 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2705
    11 #include<cmath>
    12 #include<cstdio>
    13 #define F(i,j,n) for(int i=j;i<=n;i++)
    14 typedef long long LL;
    15 LL phi(LL n){
    16     int ret=1,i;
    17     for(int i=2;i*i<=n;i++){
    18         if (n%i==0){
    19             n/=i; ret*=i-1;
    20             while(n%i==0) n/=i,ret*=i;
    21         }
    22     }
    23     if (n>1) ret*=n-1;
    24     return ret;
    25 }
    26 int main(){
    27     int n;
    28     scanf("%d",&n);
    29     long long ans=0;
    30     for(int i=1;i*i<=n;i++)
    31         if(n%i==0){
    32             ans+=(LL)i*phi(n/i);
    33             if (i*i<n) ans+=(LL)n/i*phi(i);
    34         }
    35     printf("%lld
    ",ans);
    36     return 0;
    37 }
    View Code

      但是其实对于这个函数$sum_{i|n} i*varphi(frac{n}{i})$是满足积性的,因为它就是$id(x)=x$和$varphi(x)$这两个函数的狄利克雷卷积,那么……(贴个网上的图片)

     1 /**************************************************************
     2     Problem: 2705
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:8 ms
     7     Memory:816 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2705
    11 #include<cmath>
    12 #include<cstdio>
    13 #define F(i,j,n) for(int i=j;i<=n;i++)
    14 int main(){
    15     int n;
    16     scanf("%d",&n);
    17     long long ans=n;
    18     F(i,2,sqrt(n)){
    19         if(n%i==0){
    20             int k=0;
    21             for(k;n%i==0;k++,n/=i);
    22             ans+=ans*(i-1)*k/i;
    23         }
    24     }
    25     if (n!=1) ans+=ans*(n-1)*1/n;
    26     printf("%lld
    ",ans);
    27     return 0;
    28 }
    View Code(诡异的加法版本)

    P.S.但是这个【乘起来】的过程我在网上没找到啊……写法好诡异我理解不了……所以我机(sha)智(bi)地改了一个利用快速幂的版本= =耗时居然一样……如果有哪位路过的大牛搞明白了前面那个加法版本的意思的话请留言教我一下,万分感谢。

     1 /**************************************************************
     2     Problem: 2705
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:8 ms
     7     Memory:816 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2705
    11 #include<cmath>
    12 #include<cstdio>
    13 #define F(i,j,n) for(int i=j;i<=n;i++)
    14 typedef long long LL;
    15 LL Pow(LL a,LL b){
    16     LL r=1;
    17     for(;b;b>>=1,a*=a)if(b&1)r*=a;
    18     return r;
    19 }
    20 int main(){
    21     int n;
    22     scanf("%d",&n);
    23     LL ans=1;
    24     F(i,2,sqrt(n)){
    25         if(n%i==0){
    26             int k=0;
    27             for(k;n%i==0;k++,n/=i);
    28             ans*=(k+1)*Pow(i,k)-k*Pow(i,k-1);
    29 //            ans+=ans*(i-1)*k/i;
    30         }
    31     }
    32     if (n!=1) ans*=2*Pow(n,1)-1;
    33     printf("%lld
    ",ans);
    34     return 0;
    35 }
    View Code(乘法版本)
  • 相关阅读:
    hdu 1290 献给杭电五十周年校庆的礼物 (DP)
    hdu 3123 GCC (数学)
    hdu 1207 汉诺塔II (DP)
    hdu 1267 下沙的沙子有几粒? (DP)
    hdu 1249 三角形 (DP)
    hdu 2132 An easy problem (递推)
    hdu 2139 Calculate the formula (递推)
    hdu 1284 钱币兑换问题 (DP)
    hdu 4151 The Special Number (DP)
    hdu 1143 Tri Tiling (DP)
  • 原文地址:https://www.cnblogs.com/Tunix/p/4389627.html
Copyright © 2011-2022 走看看