hdu2588 gcd 欧拉函数

GCD

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1567    Accepted Submission(s): 751

Problem Description

The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.

Input

The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.

Output

For each test case,output the answer on a single line.

Sample Input

3
1 1
10 2
10000 72

Sample Output

1
6
260

题目大意:

数据量太大,用常规方法做是行不通的。后来看了别人的解题报告说,先找出N的约数x,

          并且gcd(x,N)>= M,结果为所有N/x的欧拉函数之和。

          因为x是N的约数,所以gcd(x,N)=x >= M;

   设y=N/x,y的欧拉函数为小于y且与y互质的数的个数。

   设与y互质的的数为p1,p2,p3,…,p4

   那么gcd(x* pi,N)= x >= M。

          也就是说只要找出所有符合要求的y的欧拉函数之和就是答案了。

至于为何用ans+=Euler(n/i0而不是直接加n/i,这便是为了查重,防止出现重复

只加满足gcd(k*x,n)==x的个数,不过如果直接遍历找约数遍历的量太大,同样会

TLE,因此可以把区间右坐标变成sqrt(n),同时判断i和n/i即可,特别注意num*num=n

的情况要单独处理。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
int kase=0;
LL Euler(LL n)
{
    LL ans=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            ans-=ans/i;
            while(n%i==0) n/=i;
        }
    }
  if(n>1) ans-=ans/n;
  return ans;
}
int main()
{
    int t;
    cin>>t;
    __int64 n,m;
    while(t--)
    {
        kase=0;
        scanf("%I64d%I64d",&n,&m);
        int num=(int)sqrt(n+0.5);
        //cout<<num<<endl;
        for(int i=1;i<num;i++)
        {
            if(n%i==0)
            {
                if(n/i>=m)
                kase+=Euler(i);
                if(i>=m)
                kase+=Euler(n/i);
            }
        }
        //cout<<kase<<endl;
       // cout<<Euler(100)<<endl;
        if(num*num==n&&num>=m) kase+=Euler(num);
        cout<<kase<<endl;
    }
    return 0;
}

时间: 2024-12-13 23:56:33

hdu2588 gcd 欧拉函数的相关文章

HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少.(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000) 思路:因为x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质.要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,可以

HDU 2588 GCD (欧拉函数)

GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1013    Accepted Submission(s): 457 Problem Description The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes writt

hdu 1695 GCD 欧拉函数+容斥

题意:给定a,b,c,d,k x属于[1 , c],y属于[1 , d],求满足gcd(x,y)=k的对数.其中<x,y>和<y,x>算相同. 思路:不妨设c<d,x<=y.问题可以转化为x属于[1,c / k ],y属于[1,d/k ],x和y互质的对数. 那么假如y<=c/k,那么对数就是y从1到c/k欧拉函数的和.如果y>c/k,就只能从[ c/k+1 , d ]枚举,然后利用容斥.详见代码: /****************************

hdu 1695 GCD(欧拉函数+容斥原理)

http://acm.hdu.edu.cn/showproblem.php? pid=1695 非常经典的题.同一时候感觉也非常难. 在区间[a,b]和[c,d]内分别随意取出一个数x,y,使得gcd(x,y) = k.问这种(x,y)有多少对.能够觉得a,c均为1,并且gcd(5,7)与gcd(7,5)是同一种. 由于gcd(x,y) = k,那么gcd(x/k,y/k) = 1.也就是求区间[1,b/k]和[1,d/k]内这种(x,y)对使得gcd(x,y) = 1. 为了防止计数反复,首先

HDU 1695 GCD 欧拉函数+容斥定理

输入a b c d k求有多少对x y 使得x在a-b区间 y在c-d区间 gcd(x, y) = k 此外a和c一定是1 由于gcd(x, y) == k 将b和d都除以k 题目转化为1到b/k 和1到d/k 2个区间 如果第一个区间小于第二个区间 讲第二个区间分成2部分来做1-b/k 和 b/k+1-d/k 第一部分对于每一个数i 和他互质的数就是这个数的欧拉函数值 全部数的欧拉函数的和就是答案 第二部分能够用全部数减去不互质的数 对于一个数i 分解因子和他不互质的数包括他的若干个因子 这个

[题解](gcd/欧拉函数)luogu_P2568_GCD

求gcd(x,y)=p等价于求gcd(x/p,y/p)=1,转化为了n/p内互质的个数 所以欧拉函数,因为有序所以乘2,再特判一下只有在1,1情况下才会重复计算,所以每次都减一 数组开小一时爽,提交wa火葬场!!! #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=10000009; int n; int ck[maxn],prime[max

HDU5780 gcd 欧拉函数

http://acm.hdu.edu.cn/showproblem.php?pid=5780 BC #85 1005 思路: 首先原式化简:x?^gcd(a,b)??−1 也就是求n内,(公约数是i的对数)*x^i-1的和,其中i为n内的两两最大公约数.那么问题可以转化成先预处理出i,再求和,注意O(n*300)=1,正常情况会卡常数.必须还要优化 由于 ans=∑s[d]∗(x^?d??−1),记s[d]=最大公约数为d的对数 我们注意到求s[d] or (公约数是i的对数),也就是求n/i以

hdu 1695 GCD 欧拉函数 + 容斥

http://acm.hdu.edu.cn/showproblem.php?pid=1695 要求[L1, R1]和[L2, R2]中GCD是K的个数.那么只需要求[L1, R1 / K]  和 [L2, R2 / K]中GCD是1的对数. 由于(1, 2)和(2, 1)是同一对. 那么我们枚举大区间,限制数字一定是小于等于枚举的那个数字就行. 比如[1, 3]和[1, 5] 我们枚举大区间,[1, 5],在[1, 3]中找互质的时候,由于又需要要小于枚举数字,那么直接上phi 对于其他的,比如

BZOJ2818 Gcd 欧拉函数

题意:给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 题解:我们枚举素数p,后面的过程和BZOJ2705一样,不同的是我们限制x>=y,假定得到的答案是ans,那么实际上答案是2*ans-1(加上x<=y,x==y重复计算了) #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <