本质:求
明显k的限制可以优化
转化为莫比乌斯函数的性质
交换枚举顺序
右边两个式子本质是
容斥一下枚举根号就完了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 51000
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
x=0;
int f=1;
char ch=nc();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=nc();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=nc();
}
x*=f;
}
int a,b,c,d,k;
int sum[N]={0},mu[N]={0},is_prime[N]={0},mark[N];
int cnt=0;
void pre_mul(){
mu[1]=1;
for(int i=2;i<=50000;i++){
if(!mark[i]){
cnt++;
is_prime[cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&is_prime[j]*i<=50000;j++){
mark[is_prime[j]*i]=1;
if(i%is_prime[j]==0){
mu[is_prime[j]*i]=0;
break;
}
mu[is_prime[j]*i]=-mu[i];
}
}
sum[0]=0;
for(int i=1;i<=50000;i++){
sum[i]=mu[i]+sum[i-1];
}
}
int get_ans(int n,int m){
if(n>m)
swap(n,m);
int ans=0;
int last;
for(int i=1;i<=n;i=last+1){
last=min(n/(n/i),m/(m/i));
ans+=(n/i)*(m/i)*(sum[last]-sum[i-1]);
}
return ans;
}
int main(){
pre_mul();
int T;
// scanf("%d",&T);
read(T);
while(T--){
// scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
read(a);
read(b);
read(c);
read(d);
read(k);
a--;
c--;
a=a/k;
b=b/k;
c=c/k;
d=d/k;
// cout<<"sajh"<<endl;
int ans=get_ans(b,d)+get_ans(a,c)-get_ans(a,d)-get_ans(b,c);
printf("%d\n",ans);
}
}