正题
题目大意
求∑i=ab∑j=cd(gcd(i,j)==k)\sum_{i=a}^b\sum_{j=c}^d(gcd(i,j)==k)i=a∑bj=c∑d(gcd(i,j)==k)
解题思路
定义
f(i)=∑i=1n∑j=1m(gcd(i,j)==i)f(i)=\sum_{i=1}^n\sum_{j=1}^m(gcd(i,j)==i)f(i)=i=1∑nj=1∑m(gcd(i,j)==i)
然后计算f利用容斥计算答案
之后我们考虑如何计算
F(i)=∑dd∣if(i)F(i)=\sum^{d|i}_df(i)F(i)=d∑d∣if(i)
显然可得出
F(i)=⌊ni⌋⌊mi⌋F(i)=\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloorF(i)=⌊in⌋⌊im⌋
然后莫比乌斯反演一下
f(i)=∑d∣iμ(dk)+F(d)f(i)=\sum_{d|i}\mu(\frac{d}{k})+F(d)f(i)=d∣i∑μ(kd)+F(d)
f(i)=∑d∣iμ(dk)+⌊nd⌋⌊md⌋f(i)=\sum_{d|i}\mu(\frac{d}{k})+\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloorf(i)=d∣i∑μ(kd)+⌊dn⌋⌊dm⌋
时间复杂度降低到O(n)O(n)O(n)
之后我们可以发现⌊nd⌋\lfloor\frac{n}{d}\rfloor⌊dn⌋只有2n2\sqrt n2n种取值,那么⌊ni⌋⌊mi⌋\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloor⌊in⌋⌊im⌋最多就有2(n+m)2(\sqrt n+\sqrt m)2(n+m)种取值,我们可以直接计算这个范围内莫比乌斯函数的前缀和然后直接O(min{n,m})O(\sqrt {min\{n,m\}})O(min{n,m})计算答案
code
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#define N 50000
#define ll long long
using namespace std;
ll miu[N+10],c,d,a,b,k,t;
bool v[N+10];
void sumul()
{for(ll i=1;i<=N;i++) miu[i]=1,v[i]=0;for(ll i=2;i<=N;i++){if(v[i]) continue;miu[i]=-1;for(ll j=2*i;j<=N;j+=i){v[j]=1;if((j/i)%i==0) miu[j]=0;else miu[j]*=-1;}}for(ll i=1;i<=N;i++)miu[i]+=miu[i-1];
}
ll ask(ll n,ll m)
{if(n>m) swap(n,m);ll last,re=0;n/=k;m/=k;for(ll i=1;i<=n;i=last+1){last=min(n/(n/i),m/(m/i));re+=(n/i)*(m/i)*(miu[last]-miu[i-1]);}return re;
}
int main()
{sumul();scanf("%lld",&t);for(ll i=1;i<=t;i++){scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);printf("%lld\n",ask(b,d)+ask(a-1,c-1)-ask(a-1,d)-ask(b,c-1));}
}