题目链接:https://vjudge.net/contest/125308#problem/G
题意:求有多少x(1<=x<=n),使得gcd(x,n)>=m; 先求n的所有大于等于m的因子, 刚开始用了模拟,超时,看了下往上的题解,说要用到欧拉函数求解,就看了下欧拉函数, ans=∑phi[n/ei];phi[i]为欧拉函数,为不大于i且与i互质的正整数个数 对于一个与ei互质且小于等于n/ei的正整数p来说,p*ei<=n,gcd(p*ei,n)=ei;则phi[n/ei]就是1~n中的与n最大公约数是ei的个数。而n与1~n的最大公约数必定是n的因子。 所以符合gcd(x,n)>=m的x为n所有大于等于m因子的倍数,用phi即可避免重复。
那么此题就很容易解了
AC代码:
1 #include <stdio.h> 2 #define size 1000000 3 int a[size]; 4 5 6 int P( int n ) 7 { 8 int ans = n; 9 for( int i = 2 ; i*i <= n ; i++ ) 10 { 11 if( n%i==0 ) 12 { 13 ans = ans / i * (i-1); 14 while( n%i==0 ) 15 n /= i; 16 } 17 } 18 if(n>1) 19 ans = ans / n * (n-1); 20 return ans; 21 } 22 23 int main() 24 { 25 26 int t , n , m , t1 , ans; 27 scanf("%d",&t); 28 while( t-- ) 29 { 30 scanf("%d%d",&n,&m); 31 t1 = ans = 0; 32 for( int i = 1 ; i*i<=n ; i++ ) 33 { 34 if( n%i == 0 ) 35 { 36 if(i*i==n) 37 a[t1++] = i; 38 else 39 { 40 a[t1++] = i; 41 a[t1++] = n/i; 42 } 43 } 44 } 45 for( int i = 0 ; i<t1 ; i++ ) 46 { 47 if( a[i]>=m ) 48 { 49 ans += P( n/a[i] ); 50 } 51 } 52 printf("%d\n",ans); 53 } 54 return 0; 55 }