给定正整数 nnn,求 1≤x,y≤n1\le x,y\le n1≤x,y≤n 且 gcd(x,y)\gcd(x,y)gcd(x,y) 为素数的数对 (x,y)(x,y)(x,y) 有多少对。
n≤107n\le 10^7n≤107
题解
做法1
题意即为求S=∑质数p∣n∑i=1n∑j=1n[gcd(i,j)=p]S=\sum_{质数p|n}\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)=p]S=∑质数p∣n∑i=1n∑j=1n[gcd(i,j)=p]
常规操作化简S=∑质数p∣n∑i=1⌊np⌋∑j=1⌊np⌋[gcd(i,j)=1]S=\sum_{质数p|n}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{p}\rfloor}[\gcd(i,j)=1]S=∑质数p∣n∑i=1⌊pn⌋∑j=1⌊pn⌋[gcd(i,j)=1]
如果我们记n′=⌊np⌋,f(i)=∑a=1n′∑b=1n′[gcd(a,b)=i],g(i)=∑i∣df(d)n'={\lfloor\frac{n}{p}\rfloor},f(i)=\sum_{a=1}^{n'}\sum_{b=1}^{n'}[\gcd(a,b)=i],g(i)=\sum_{i|d}f(d)n′=⌊pn⌋,f(i)=∑a=1n′∑b=1n′[gcd(a,b)=i],g(i)=∑i∣df(d)
则展开g(i)g(i)g(i)有
g(i)=∑i∣d∑a=1n′∑b=1n′[gcd(a,b)=d]g(i)=\sum_{i|d}\sum_{a=1}^{n'}\sum_{b=1}^{n'}[\gcd(a,b)=d]g(i)=i∣d∑a=1∑n′b=1∑n′[gcd(a,b)=d]
常规操作g(i)=∑a=1n′∑b=1n′[i∣gcd(a,b)]=∑a=1⌊n′i⌋∑b=1⌊n′i⌋[1∣gcd(a,b)]=⌊n′i⌋2g(i)=\sum_{a=1}^{n'}\sum_{b=1}^{n'}\left[i|\gcd(a,b)\right]=\sum_{a=1}^{\lfloor\frac{n'}{i}\rfloor}\sum_{b=1}^{\lfloor\frac{n'}{i}\rfloor}[1|gcd(a,b)]=\left\lfloor\frac{n'}{i}\right\rfloor^2g(i)=∑a=1n′∑b=1n′[i∣gcd(a,b)]=∑a=1⌊in′⌋∑b=1⌊in′⌋[1∣gcd(a,b)]=⌊in′⌋2
所以S=∑质数p∣nf(p)=∑质数p∣n∑d=1dp≤nμ(d)g(p)=∑质数p∣n∑d=1pd≤nμ(d)⌊ndp⌋2S=\sum_{质数p|n}f(p)=\sum_{质数p|n}\sum_{d=1}^{dp\le n}\mu\left(d\right)g(p)=\sum_{质数p|n}\sum_{d=1}^{pd\le n}\mu(d)\left\lfloor\frac{n}{dp}\right\rfloor^2S=∑质数p∣nf(p)=∑质数p∣n∑d=1dp≤nμ(d)g(p)=∑质数p∣n∑d=1pd≤nμ(d)⌊dpn⌋2
接着有设T=dpT=dpT=dp,这里由于p,dp,dp,d具有对称性,交换求和次序有S=∑T=1n⌊nT⌋2∑质数p∣Tμ(Tp)S=\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor^2\sum_{质数p|T}\mu\left({\frac{T}{p}}\right)S=∑T=1n⌊Tn⌋2∑质数p∣Tμ(pT)
然后∑T=1n⌊nT⌋2\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor^2∑T=1n⌊Tn⌋2可以整除分块,而后面的可以在筛一遍质数之后O(n)O(\sqrt{n})O(n)求出,于是复杂度就是O(n)O(n)O(n),实际上远远跑不满
做法2
事实上,因为数对具有对称性,我们可以将SSS稍稍变形得到
S=∑质数p∣n∑i=1⌊np⌋∑j=1⌊np⌋[gcd(i,j)=1]=∑质数p∣n(2∑i=1⌊np⌋∑j=1i[gcd(i,j)=1]−1)S=\sum_{质数p|n}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{p}\rfloor}[\gcd(i,j)=1]=\sum_{质数p|n}\left(2\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^i[\gcd(i,j)=1]-1\right)S=∑质数p∣n∑i=1⌊pn⌋∑j=1⌊pn⌋[gcd(i,j)=1]=∑质数p∣n(2∑i=1⌊pn⌋∑j=1i[gcd(i,j)=1]−1)
这个−1-1−1是因为不能让(p,p)(p,p)(p,p)统计两次,根据φ\varphiφ的定义,会发现原式等价于∑质数p∣n(2∑i=1⌊np⌋φ(i)−1)\sum_{质数p|n}\left(2\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\varphi(i)-1\right)∑质数p∣n(2∑i=1⌊pn⌋φ(i)−1)
预处理欧拉函数前缀和即可线性求解
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000005
#define int long long
int n, phi[N], prime[N], v[N], cnt, s[N];
int init() {
phi[1] = 1;
scanf("%lld", &n);
for (int i = 2; i <= n; i++) {
if (!v[i]) {
v[i] = i;
prime[++cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= cnt; j++) {
if (prime[j] > v[i] || prime[j] * i > n)break;
v[prime[j] * i] = prime[j];
phi[prime[j] * i] = i % prime[j] ? phi[i] * (prime[j] - 1) : phi[i] * prime[j];
}
}
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + phi[i];
}
return 0;
}
void solve() {
int m = n, ans = 0;
for (int i = 1; i <= cnt; i++) {
ans += s[m / prime[i]] << 1;
ans--;
}
printf("%lld", ans);
return;
}
signed main() {
init();
solve();
return 0;
}

52

被折叠的 条评论
为什么被折叠?



