Hillan and the girl
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Problem Description
“WTF!
While everyone has his girl(gay) friend, I only have my keyboard!”
Tired of watching others‘ affair, Hillan burst into scream, which made
him decide not to hold it back.
“All right, I am giving you a
question. If you answer correctly, I will be your girl friend.” After
listening to Hillan, Girl replied, “What is the value of ∑ni=1∑mj=1f(i,j), where f(i,j)=0 if gcd(i,j) is a square number and f(i,j)=1 if gcd(i,j) is not a square number(gcd(i,j) means the greatest common divisor of x and y)?”
But Hillan didn‘t have enough Intelligence Quotient to give the right answer. So he turn to you for help.
Input
The first line contains an integer T(1≤T≤10,000)——The number of the test cases.
For each test case, the only line contains two integers n,m(1≤n,m≤10,000,000) with a white space separated.
Output
For each test case, the only line contains a integer that is the answer.
Sample Input
2
1 2333333
10 10
Sample Output
0
33
Hint
In the first test case, obviously $f\left(i,j\right)$ always equals to 0, because $i$ always equals to 1 and $\gcd\left(i,j\right)$ is always a square number(always equals to 1).
Source
min(n,m) min(n/k,m/k)
思路:首先推到∑ ∑ mu(d) * [n/k/d] * [m/k/d]; k为完全平方数;
k=1 d=1
令T=k*d;
可得:
min(n,m)
∑ [n/T] * [m/T] ∑ mu(T/k) ;
T k|T
令gg数组等于 ∑ mu(T/k) 相当于原来的mu函数;
k|T
和原来一样分块即可;
#include<bits/stdc++.h> using namespace std; #define ll __int64 #define esp 0.00000000001 #define pi 4*atan(1) const int N=1e7+10,M=1e7+10,inf=1e9+10,mod=1e9+7; int mu[N], p[N], np[N], cnt, sum[N]; ll gg[N]; void init() { mu[1]=1; for(int i=2; i<N; ++i) { if(!np[i]) p[++cnt]=i, mu[i]=-1; for(int j=1; j<=cnt && i*p[j]<N; ++j) { int t=i*p[j]; np[t]=1; if(i%p[j]==0) { mu[t]=0; break; } mu[t]=-mu[i]; } } for(int i=1;i*i<N;i++) { for(int t=i*i;t<N;t+=(i*i)) sum[t]+=mu[t/i/i]; } for(int i=1;i<N;i++) gg[i]=gg[i-1]+sum[i]; } ll getans(ll b,ll d) { if(b>d)swap(b,d); ll ans=0; for(ll L=1,R=0;L<=b;L=R+1) { R=min(b/(b/L),d/(d/L)); ans+=(b/L)*(d/L)*(gg[R]-gg[L-1]); } return ans; } int main() { int T; init(); scanf("%d",&T); while(T--) { ll b,d; scanf("%I64d%I64d",&b,&d); printf("%I64d\n",(b*d)-getans(b,d)); } return 0; }