题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2588
思路
欧拉函数值的意思是[1,n]中gcd(x,n)=1的x的个数,x[1,n]
如果x[1,n],且gcd(x,n)=k,令x=k*a,n=k*b,那么a与b互质
由x≤n可知a≤b,所以求a的个数相当于转化为求[1,b]中和b互质的数的个数,,即,其中k[m+1,n]
注意:k必须是n的约数,这道题n过大,分一半求即可,O(√n)
代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#define maxn 10000
typedef long long ll;
const ll mod=1e9+7;
using namespace std;
ll euler(ll x)
{
ll ans=x;
for(ll i=2;i*i<=x;i++)
{
if(x%i==0)
{
ans=ans/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x!=1) ans=ans/x*(x-1);
return ans;
}
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
ll n,m,t;
cin>>t;
while(t--)
{
ll ans=0;
vector<ll> div;
cin >> n >> m;
for(ll i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i*i==n)
{
if(i>=m) div.push_back(i);
}
else
{
if(i>=m) div.push_back(i);
if(n/i>=m) div.push_back(n/i);
}
}
}
for (ll i = 0 ; i <div.size(); i++)
ans += euler(n/div[i]);
cout << ans << endl;
}
}