[洛谷P2257] YY的GCD
阿新 • • 發佈:2018-03-04
return rim math tput blog space 結果 long 多少
設 \(T=dp\)
則
\[ ans=\sum\limits_{T=2}^{min(n,m)} \lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor \sum\limits_{p|T 且p為質數} \mu(\frac{T}{p}) \]
預處理計算每個數 \(T\) 的 \(\sum\limits_{p|T 且p為質數} \mu(\frac{T}{p})\) 及其前綴和
用每個質數把自己的倍數篩一遍就行了。
Description
神犇YY虐完數論後給傻×kAc出了一題
給定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)為質數的(x, y)有多少對
kAc這種傻×必然不會了,於是向你來請教……
多組輸入
Input
第一行一個整數T 表述數據組數
接下來T行,每行兩個正整數,表示N, M
Output
T行,每行一個整數表示第i組數據的結果
Sample Input
2
10 10
100 100
Sample Output
30
2791
HINT
T = 10000
N, M <= 10000000
想法
Orz PoPoQQQ大神……
若枚舉每個質數 \(p\)
則
\[
\begin{equation*}
\begin{aligned}
ans&= \sum\limits_p \sum\limits_{p|k} \mu(\frac{k}{p}) F(k) \ &= \sum\limits_p \sum\limits_{d=1}^{\frac{min(n,m)}{p}} \mu(d) \lfloor \frac{n}{dp} \rfloor \lfloor \frac{m}{dp} \rfloor
\end{aligned}
\end{equation*}
\]
設 \(T=dp\)
則
\[ ans=\sum\limits_{T=2}^{min(n,m)} \lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor \sum\limits_{p|T 且p為質數} \mu(\frac{T}{p}) \]
預處理計算每個數 \(T\) 的 \(\sum\limits_{p|T 且p為質數} \mu(\frac{T}{p})\) 及其前綴和
用每個質數把自己的倍數篩一遍就行了。
代碼
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 10000005;
int mu[N];
ll sum[N];
int prime[N],pnum,p[N];
int getmu(){
mu[1]=1;
for(int i=2;i<N;i++) p[i]=1;
for(int i=2;i<N;i++){
if(p[i]) {
prime[pnum++]=i;
mu[i]=-1;
}
for (int j=0;j<pnum && (ll)prime[j]*i<N;j++){
p[i*prime[j]]=0;
if(i%prime[j]==0) {
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
for(int i=0;i<pnum;i++)
for(int j=1;(ll)j*prime[i]<N;j++)
sum[j*prime[i]]+=mu[j];
sum[1]=0;
for(int i=2;i<N;i++) sum[i]+=sum[i-1];
}
int n,m,T;
int main()
{
getmu();
scanf("%d",&T);
ll ans;
while(T--){
scanf("%d%d",&n,&m);
ans=0;
for(int l=2,r;l<=min(n,m);l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
}
printf("%lld\n",ans);
}
return 0;
}
[洛谷P2257] YY的GCD