• 51nod 1040 最大公约数之和


    分析:只要求出每个最大公约数出现的次数就可以了,而最大公约数必然是n的因子,考虑n的任意一个因子m,设t满足gcd(t,n)=m,等价于gcd(t/m,n/m)=1,由t<=n的t/m<=t/m,也就是说,这样的t的个数恰好是φ(n/m)个,故结果就是(m|n)∑m*φ(n/m).复杂度为O((logn)^2).

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<vector>
      5 using namespace std;
      6 typedef long long ll;
      7 int prinum[10000],len=0;
      8 ll Fai(int n0){
      9     int n=n0;
     10     if(n==1)return 1;
     11     for(int i=0;i<len;i++){
     12         if(n%prinum[i]==0){
     13             int t=1;
     14             while(n%prinum[i]==0){
     15                 n/=prinum[i];
     16                 t*=prinum[i];
     17             }
     18             if(n==1){
     19                 return (ll)n0-t/prinum[i];
     20             }
     21             return Fai(t)*Fai(n);
     22         }
     23     }
     24     return n0-1;
     25 }
     26 struct Pair{
     27     int x,y;
     28 };
     29 void CalPri(){
     30     int num[50000];
     31     for(int i=0;i<50000;i++)num[i]=i;
     32     for(int i=2;i<50000;i++){
     33         if(num[i]==0)continue;
     34         prinum[len++]=i;
     35         for(int j=2*i;j<50000;j+=i)
     36             num[j]=0;
     37     }
     38 }
     39 void decompose(int n,vector<Pair> &v){
     40     v.clear();
     41     Pair p;
     42     for(int i=0;i<len&&prinum[i]<=n;i++){
     43         if(n%prinum[i]==0){
     44             p.x=prinum[i];
     45             p.y=0;
     46             while(n%prinum[i]==0){
     47                 n/=prinum[i];
     48                 p.y++;
     49             }
     50             v.push_back(p);
     51         }
     52     }
     53     if(n!=1){
     54         p.x=n;
     55         p.y=1;
     56         v.push_back(p);
     57     }
     58 }
     59 ll qpow(int a,int n){
     60     ll k=1,y=a,ans=1;
     61     while(k){
     62         if(k&n)ans*=y;
     63         y*=y;
     64         k<<=1;
     65     }
     66     return ans;
     67 }
     68 ll solve(int n){
     69     vector<Pair> v;
     70     decompose(n,v);
     71     int r[100];
     72     ll result=0,m;
     73     memset(r,0,sizeof(r));
     74     int i=v.size()-1;
     75     while(i>=0){
     76         m=1;
     77         for(int j=0;j<v.size();j++){
     78             m*=qpow(v[j].x,r[j]);
     79         }
     80         result+=m*Fai(n/m);
     81         if(r[i]>=v[i].y){
     82             while(i>=0&&r[i]>=v[i].y){
     83                 i--;
     84             }
     85             if(i==-1)break;
     86             r[i]++;
     87             memset(r+i+1,0,sizeof(r)-(i+1)*sizeof(int));
     88             i=v.size()-1;
     89         }
     90         else r[i]++;
     91     }
     92     return result;
     93 }
     94 int main(){
     95     CalPri();
     96     int n;
     97     cin>>n;
     98     if(n==1)cout<<1<<endl;
     99     else cout<<solve(n)<<endl;
    100     return 0;
    101 }
  • 相关阅读:
    下载安装Git,学习笔记
    php面试相关整理
    2.5 DQL 分组查询
    2.4 DQL 常见函数
    2.3 DQL 排序查询
    2.2 DQL 条件查询
    2.1 DQL 基础查询
    1.2 MySQL的介绍
    1.1 数据库的相关概念
    2019年JavaEE学习线路
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7056453.html
Copyright © 2020-2023  润新知