标签:def cout return name efi font main 一加 scanf
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k
共n行,每行一个整数表示满足要求的数对(x,y)的个数
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000
思路{
n/k,m/k,转化为gcd(i,j)==1,
那么直接上套路莫比乌斯反演+数论分块就可以了,
再区间加一加,减一减就可以了.
}
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define il inline
#define N 50200
#define LL long long
using namespace std;
bool vis[N];
LL p[N],mu[N];
void pre(){
mu[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])mu[i]=-1,p[++p[0]]=i;
for(int j=1;j<=p[0]&&p[j]*i<N;++j){
vis[i*p[j]]=true;
if(i%p[j])mu[i*p[j]]=-mu[i];
else {
mu[i*p[j]]=0;
break;
}
}
}for(int i=2;i<N;++i)mu[i]+=mu[i-1];
}
LL cal(int n,int m){
LL ans=0;
if(n>m)swap(n,m);
for(int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(mu[r]-mu[l-1])*(n/l)*(m/l);
}return ans;
}
int main(){
int T;scanf("%d",&T);pre();
while(T--){
int a,b,c,d,k;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
a--,c--;a/=k,b/=k,c/=k,d/=k;
cout<<cal(b,d)+cal(a,c)-cal(a,d)-cal(c,b)<<"\n";
}return 0;
}
标签:def cout return name efi font main 一加 scanf
原文地址:http://www.cnblogs.com/zzmmm/p/7476563.html