# [bzoj2301] [HAOI2011]Problem b

## Sample Input

2
2 5 1 5 1
1 5 1 5 2


## Sample Output

14
3


## HINT

100%的数据满足：1≤n≤50000，1≤a≤b≤50000，1≤c≤d≤50000，1≤k≤50000

# 题解

$ans = \sum _ {i=a}^b \sum _ {j=c}^d [gcd(i,j)=k]$

$ans = \sum _ {i=1}^n \sum _ {j=1}^m [gcd(i,j)=k]$

$k$除掉：

$ans= \sum _ {i=1}^{\lfloor \frac{n}{k} \rfloor} \sum _ {j=1}^{\lfloor \frac{m}{k} \rfloor} [gcd(i,j)=1]$

$\sum _{d|n} \mu(d) =[ n=1 ]$

$ans= \sum _ {i=1}^{\lfloor \frac{n}{k} \rfloor} \sum _ {j=1}^{\lfloor \frac{m}{k} \rfloor} \sum _{d|i\&d|j} \mu(d)$

\begin {align} ans&= \sum _d\mu(d) \sum _{i=1}^{\lfloor \frac{n}{kd} \rfloor} \sum _{j=1}^{\lfloor \frac{m}{kd} \rfloor} 1 \\ &= \sum _d\mu(d) \lfloor \frac{n}{kd} \rfloor \lfloor \frac{m}{kd} \rfloor \\ \end {align}

#include<bits/stdc++.h>
using namespace std;

#define int long long

void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

const int maxn = 5e4+10;

int mu[maxn],pri[maxn],vis[maxn],tot,T;

void sieve() {
mu[1]=1;
for(int i=2;i<maxn;i++) {
if(!vis[i]) pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*pri[j]<maxn;j++) {
vis[i*pri[j]]=1;
if(!(i%pri[j])) {mu[i*pri[j]]=0;break;}
else mu[i*pri[j]]=-mu[i];
}
}
for(int i=1;i<maxn;i++) mu[i]=mu[i]+mu[i-1];
}

int calc(int n,int m,int k) {
int d=1,ans=0;n/=k,m/=k;
while(d<=n&&d<=m) {
int pre=d;d=min(n/(n/d),m/(m/d));
ans+=(n/d)*(m/d)*(mu[d]-mu[pre-1]);
d++;
}return ans;
}

signed main() {
sieve();read(T);
for(int i=1,a,b,c,d,k;i<=T;i++) {
read(a),read(b),read(c),read(d),read(k);
write(calc(b,d,k)-calc(b,c-1,k)-calc(a-1,d,k)+calc(a-1,c-1,k));
}
return 0;
}


posted @ 2018-12-02 11:34  Hyscere  阅读(64)  评论(0编辑  收藏