hdu2588(尤拉函式的運用)
阿新 • • 發佈:2019-02-09
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.
題意:給定n,m,求在1~n之間有多少個數,也就是x,gcd(x,n)>=m
解題思路:n的範圍很大,不能列舉1~n,好像與gcd有關的題都要用到尤拉函式。。。
所以換個思路,假如n的一個因子fac>=m,則設n=fac*k,原式就變為gcd(x,fac*k)>=m,如何才能滿足這個式子呢?
當然要x與k互質,當gcd(x,k)==1時(也就是互質),gcd(x,fac*k)==fac>=m,成立!
所以我們就要找與k互質的數的個數,也就是n/fac的尤拉函式值,最後處理一下fac和k相等的情況即可
#include <bits/stdc++.h> using namespace std; int Euler(int n) { int num=n; for(int i=2; i<=sqrt(n); i++) if(n%i==0) { num=num/i*(i-1);//先進行除法防止溢位(num=num*(1-1/p(i))) while(n%i==0) n/=i; } if(n>1) num=num/n*(n-1); return num; } int main() { int t; cin>>t; while(t--) { int m,n,ans; ans=0; cin>>n>>m; for(int i=1; i<=sqrt(n); i++) { if(n%i==0)//列舉每一個因子 { if(n/i>=m && i!=(n/i))//fac[i]==i的話就計算了兩次 ans+=Euler(i); if(i>=m) ans+=Euler(n/i); } } cout<<ans<<endl; } return 0; }