题目大意:给定 a,b,c,d,求 ∑bi=a∑dj=cgcd(i,j)
∑i=1n∑j=1mgcd(i,j)=∑d=1nd∑i=1⌊nd⌋∑j=1⌊md⌋[gcd(i,j)==1]=∑d=1nd∑i=1⌊nd⌋∑j=1⌊md⌋∑g|i,jμ(g)=∑d=1nd∑g=1⌊nd⌋μ(g)⌊ngd⌋⌊mgd⌋
然后就随便搞了嘛QAQ
大水怪,嘿嘿嘿
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cmath>
#include<cstring>
#include<string>
#define LL long long
#define N 50002
#define M 1000000007
using namespace std;
int tot,T,n,m,a,b,c,d;
int miu[N],prime[N],v[N];
void get_prime()
{
miu[1]=1;
for (int i=2;i<N;i++)
{
if (!v[i]) miu[prime[tot++]=i]=-1;
for (int j=0;j<tot&&i*prime[j]<N;j++)
{
v[i*prime[j]]=true;
if (i%prime[j]==0) break;
miu[i*prime[j]]=-miu[i];
}
}
for (int i=2;i<N;i++) (miu[i]+=miu[i-1])%=M;
}
LL sum(int n,int m)
{
LL ret=0;
for (int i=1,j;i<=n;i=j+1)
{
j=min(m/(m/i),n/(n/i));
(ret+=(LL)(miu[j]-miu[i-1])*(n/i)*(m/i))%=M;
}
return ret;
}
LL cal(int n,int m)
{
if (!n||!m) return 0;
LL ret=0;
if (n>m) swap(n,m);
for (int i=1,j;i<=n;i=j+1)
{
j=min(m/(m/i),n/(n/i));
(ret+=(LL)(j-i+1)*(i+j)/2%M*sum(n/i,m/i))%=M;
}
return ret;
}
int main()
{
scanf("%d",&T);
scanf("%d%d",&n,&m);
get_prime();
while (T--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
cout<<(cal(c,d)+cal(a-1,b-1)-cal(c,b-1)-cal(a-1,d)+M+M)%M<<endl;
}
return 0;
}