zoukankan      html  css  js  c++  java
  • UVa11424 GCD

    直接两重循环O(n^2)算gcd……未免太耗时

    枚举因数a和a的倍数n,考虑gcd(i,n)==a的i数量(i<=n)

    由于gcd(i,n)==a等价于gcd(i/a,n/a)==1,所以满足gcd(i,n)==a的数有phi[n/a]个

    打出欧拉函数表,枚举因数,计算出每个n的f[n]=gcd(1,n)+gcd(2,n)+gcd(3,n)+...+gcd(n-1,n)

    然后求f[n]的前缀和,回答询问。

     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=200010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int pri[mxn],cnt=0;
    16 long long phi[mxn],f[mxn];
    17 void PHI(){
    18     for(int i=2;i<mxn;i++){
    19         if(!phi[i]){
    20             phi[i]=i-1;
    21             pri[++cnt]=i;
    22         }
    23         for(int j=1;j<=cnt && (long long)i*pri[j]<mxn;j++){
    24             if(i%pri[j]==0){
    25                 phi[i*pri[j]]=phi[i]*pri[j];
    26                 break;
    27             }
    28             else phi[i*pri[j]]=phi[i]*(pri[j]-1);
    29         }
    30     }
    31     return;
    32 }
    33 int main(){
    34     PHI();
    35     int i,j;
    36     for(i=1;i<mxn;i++){//枚举因数 
    37         for(j=i*2;j<mxn;j+=i){
    38             f[j]+=i*phi[j/i];
    39         }
    40     }
    41     for(i=3;i<mxn;i++)f[i]+=f[i-1];
    42     while(1){
    43         i=read();
    44         if(!i)break;
    45         printf("%lld
    ",f[i]);
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    推荐系统相关算法
    特征的生命周期
    数学知识索引
    蓄水池(Reservoir_sampling)抽样算法简记
    数赛刷题代码学习及课程学习链接
    逻辑回归(LR)总结复习
    我的面试问题记录
    开发中遇到的一些问题
    K-Means聚类和EM算法复习总结
    常见概率分布图表总结
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6280370.html
Copyright © 2011-2022 走看看