zoukankan      html  css  js  c++  java
  • Bzoj2705 Longge的问题

    Time Limit: 3000MS   Memory Limit: 131072KB   64bit IO Format: %lld & %llu

    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

    SDOI2012

    求Σgcd(i,n) (1<=i<=n)

    暴力枚举当然可行,但是TLE不可避。

    考虑转化问题,从1到n的范围内,有许多个i的gcd(i,n)等于同一个n的因数。我们可以枚举n的每一个因数k,累计“以该数k为解的gcd(i,n)的个数s(k)"乘以该数,就能得到答案。

    若有gcd(n,m)=k,那么n和m同除公约数k后,可以得到gcd(n/k,m/k)=1。由前式可知(m/k)与(n/k)互质。满足条件的(m/k)个数,也就是s(k)就等于phi(n/k) ←欧拉函数!

    解1:直接套模板。算法无误,但是因为题目数据大,保存函数后再处理会RE(原因目测是存储用数组开不了那么大)

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int maxn=100000;
     9 long long n;
    10 int m[maxn],phi[maxn],p[maxn],pt;
    11 int euler()
    12 {
    13     phi[1]=1;
    14     int N=maxn;
    15     int k;
    16     for(int i=2;i<N;i++)
    17     {
    18         if(!m[i])//i是素数
    19             p[pt++]=m[i]=i,phi[i]=i-1;
    20         for(int j=0;j<pt&&(k=p[j]*i)<N;j++)
    21         {
    22             m[k]=p[j];
    23             if(m[i]==p[j])//为了保证以后的数不被再筛,要break
    24             {
    25                 phi[k]=phi[i]*p[j];
    26 /*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/
    27                 break;    
    28             }
    29             else
    30                 phi[k]=phi[i]*(p[j]-1);//积性函数性质,f(i*k)=f(i)*f(k)
    31         }
    32     }
    33 }
    34 int main(){
    35     euler();
    36     scanf("%lld",&n);
    37     long long m=sqrt(n);
    38     int i,j;
    39     long long ans=0;
    40     for(i=1;i<=m;i++){
    41         if(n%i==0){
    42             ans+=phi[n/i]*i;
    43             ans+=(n/i)*phi[i];
    44         }
    45     }
    46     printf("%lld
    ",ans);
    47     return 0;
    48 }

    解2:多花点时间,每次都算一遍。并不会TLE,神奇

    代码是从hzw学长那学到的,精简得很。

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int mxn=100000;
     9 long long n,m;
    10 long long phi(long long x){
    11     long long a=x;
    12     for(long long i=2;i<=m;i++){
    13         if(x%i==0){//找到因数 
    14             a=a/i*(i-1);//基本计算公式 a*=((i-1)/i) 
    15             while(x%i==0)x/=i;//除去所有相同因数 
    16         }
    17     }
    18     if(x>1)a=a/x*(x-1);//处理最后一个大因数 
    19     return a;
    20 }
    21 int main(){
    22     scanf("%lld",&n);
    23     m=sqrt(n);
    24     int i,j;
    25     long long ans=0;
    26     for(i=1;i<=m;i++){
    27         if(n%i==0){
    28             ans+=phi(n/i)*i;
    29             ans+=(n/i)*phi(i);
    30         }
    31     }
    32     printf("%lld
    ",ans);
    33     return 0;
    34 }
  • 相关阅读:
    Struts2:<s:action>的使用
    Struts2:Struts2在jsp中使用标签时值的获取
    jsp:useBean的使用
    关于Filter的一点误解
    Strust2: 工作流程
    java程序连接MySQL数据库
    python 开发工具简介
    NCEP CFSR数据下载
    美国NOAA/AVHRR遥感数据
    气象网站
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5656723.html
Copyright © 2011-2022 走看看