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.
(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.
InputThe 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.OutputFor each test case,output the answer on a single line.Sample Input
3 1 1 10 2 10000 72
Sample Output
1 6 260
题意:给你一个t表示测试组数,每一组数据给你两个数n,m(范围2~1e8),求在小于等于n的数中,有多少数满足gcd(i,n)>=m;
思路:很明显是一个欧拉函数,但是它的gcd不是一是m,因此我们要把它化为m,gcd为一,乘上m,gcd不就是m了吗
因此,我们要找n所有因子,
- 当因子p大于等于m的时, n = p *n/p,这个时候只要知道n/p的欧拉值就可以了euler(n/p),表示的gcd为一,*p,gcd就是p>=m;
- 当因子p,有n/p>=m时,并且保证 n/p !=p,这个时候只要知道p的欧拉值就可以了euler(p),表示的gcd为一,*n/p,gcd就是n/p>=m;
- 两者之间是没有重复的,唯一存在可能重复的就是当n/p=p的时候,特判一下就可以了euler(p),and euler(n/p) 会有重复的部分,但他们的乘项不同,乘出的结果也就不同
#include <iostream> #include <cstdio> #include <string> #include <algorithm> #include <map> #define Mod 1000000007 using namespace std; typedef long long ll; const ll N = 3000000+10; map<ll,ll> elh; long long a,b; ll sum [N]; ll Euler(ll n) { if(n==1)return 1; ll res =n; for(ll i=2;i<=n/i;i++) { if(n%i==0) { res = res -res/i; } while(n%i==0)n/=i; } if(n>1)res -= res/n; return res; } int main() { int t; cin >>t; while(t--) { scanf("%lld%lld",&a,&b); ll sum =0; for(int i=1;i<=a/i;i++) { if(a%i==0) { if(i>=b) { sum +=Euler(a/i); } if(a/i>=b&&a/i!=i) { sum+=Euler(i); } } } cout <<sum<<endl; } return 0; }
不管前方的路有多么曲折,我都会告诉自己,自己的选择,没有后悔,后退的可能,因为热爱所以坚持,既然已经走上这条路,就走出一点风采!!!