hdu 2841 Visible Trees

时间:2023-03-08 21:54:34
 /**
大意: 求[1,m], [1,n] 之间有多少个数互素。。。做了 1695 ,,这题就so easy 了
**/
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const long long maxn = ;
long long phi[maxn];
long long priD[maxn];
int len ; void euler(long long n){
long long m = (int )sqrt(n+0.5);
len =;
for(int i=;i<=m;i++)if(n%i==){
priD[len++] = i;
while(n%i==)
n = n/i;
}
if(n>)
priD[len++] = n;
} void phi_table(){
for(int i=;i<maxn;i++)
phi[i] =;
phi[] =;
for(int i=;i<maxn;i++)if(!phi[i]){
for(int j=i;j<maxn;j+=i){
if(!phi[j]) phi[j] =j;
phi[j] = phi[j]/i*(i-);
}
}
} long long solve(long long m){
long long sum = ;
long long flag,tmp;
for(int i=;i<1ll<<len;i++){
tmp =;
flag =;
for(int j=;j<len;j++){
if(i&(1ll<<j)){
tmp *= priD[j];
flag++;
}
}
if(flag%)
sum += m/tmp;
else
sum -= m/tmp;
}
return sum;
} int main()
{
phi_table();
int t;
cin>>t;
long long n,m;
while(t--){
cin>>m>>n;
if(m>n) //我们先默认 n > m, 不符合交换
swap(n,m);
long long sum =;
for(int i=;i<=m;i++)
sum += phi[i];
sum = sum*-;
for(int i=m+;i<=n;i++){
euler(i);
sum += (m-solve(m));
}
cout<<sum<<endl;
}
return ;
}