• HDU 2588 GCD


    原题链接:点击此处

    题意:

      第一行输入T,表示有T组数据。然后每一行输入N和M,分别表示所要求数的范围为1~N,比较值为M。
     题目意思很简单,就是求解,在数的范围内X∈[1~N],存在多少个X使得GCD(X,N)>=M,统计X符合要求的个数。
     用膝盖骨想想也知道,如果直接暴力遍历N次,每次操作的复杂度高达10^9,肯定会超时的。常规的方法肯定不行。
     

    思路: 

    我们仔细观察可得,N=a*d,X=b*d。(d即为N与X的最大公约数),题意要求的便是d≥m的情况。
      转换一下思维:因为X=b*d,而题意要求的是d≥m的情况有多少,换句话即是,要求有多少个b。再来看看,N=a*d,X=b*d。
      即a与b互质,那么便可使用欧拉函数了,欧拉函数的定义是:a的欧拉函数便是与a互质并且小于a的所有数的个数。
      但是单单枚举a的欧拉函数还是会超时,那怎么办呢?可以采用二分的方法。
      当i<√N时,我们假设d=N/i,那么此时,a=i;
      如此可得当i>√N时,有a=n/i,d=i;
      当i=√N时,a*d=N;
     
    源程序:
    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int euler(int n)//欧拉公式
    {
        int res=n;
        for(int i=2;i*i<=n;i++)
            {
                if(n%i==0)
            {
               res -= res/i;
               while(n%i==0) n/=i;
            }
        }
        if(n>1) res-=res/n;
        return res;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            int ans=0;
            for(int i=1;i*i<=n;i++)
                {
                    if(n%i==0)
                {
                    if(i>=m)ans+=euler(n/i); //计算sqrt(n)左边的
                    if(n/i>=m&&i*i!=n) ans+=euler(i);//计算sqrt(n)右边的i*i==n时,在上个语句已经执行
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    汉字转拼音
    多数组求笛卡尔积
    curl post参数,接口接收不到数据问题
    判断IMEI或MEID是否合法
    javascript 可控速度的上下拉菜单
    去掉android点击事件产生的半透明蓝色背景
    go.js是什么
    jQuery效果——动画
    jQuery选择器
    vue全局组件局部组件的使用
  • 原文地址:https://www.cnblogs.com/gdvxfgv/p/5744203.html
Copyright © 2020-2023  润新知