推G(x)的时候好神啊!!!
题解:http://blog.csdn.net/popoqqq/article/details/42122413
#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
char c;
inline void read(int&a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
const int Maxn=10000001;
int Prime[Maxn],tot,G[Maxn],Pow[Maxn],Maxp[Maxn];
bool Check[Maxn];
ll ans;
inline int min(int a,int b){return a<b?a:b;}
int main()
{
ll k;
int T,n,m,i,j;
for(i=2;i<Maxn;i++)
{
if(!Check[i])Prime[++tot]=i,G[i]=Pow[i]=1,Maxp[i]=i;
for(j=1;j<=tot;j++)
{
k=i*Prime[j];
if(k>=Maxn)break;
Check[k]=1;
if(i%Prime[j])
{
Pow[k]=1,Maxp[k]=Prime[j];
if(Pow[i]==1)G[k]=-G[i];
}
else
{
Pow[k]=Pow[i]+1,Maxp[k]=Maxp[i]*Prime[j],n=i/Maxp[i];
if(n==1)G[k]=1;
else G[k]=Pow[n]==Pow[k]?-G[n]:0;
break;
}
}
}
for(i=2;i<Maxn;i++)
G[i]+=G[i-1];
read(T);
while(T--)
{
read(n),read(m);
for(ans=0,i=1;i<=n&&i<=m;i=j+1)
j=min(n/(n/i),m/(m/i)),ans+=(ll)(G[j]-G[i-1])*(n/i)*(m/i);
printf("%lld\n",ans);
}
return 0;
}