luogu P3327 [SDOI2015]约数个数和
作者:互联网
\[\begin{aligned}
\sum\limits_{i=1}^n\sum\limits_{j=1}^m d(ij)&=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x|i}\sum\limits_{y|j} [(x,y)=1]\\
&=\sum\limits_{x=1}^n\sum\limits_{y=1}^m[(x,y)=1]\lfloor \frac{n}{x}\rfloor \lfloor\frac{m}{y}\rfloor\\
&=\sum\limits_{x=1}^n\sum\limits_{y=1}^m\sum\limits_{d|x,y}\mu(d)\lfloor \frac{n}{x}\rfloor \lfloor\frac{m}{y}\rfloor\\
&=\sum\limits_{d=1}^n\mu(d)\sum\limits_{x=1}^{n/d}\sum\limits_{y=1}^{m/d}\lfloor \frac{n}{xd}\rfloor \lfloor\frac{m}{yd}\rfloor\\
&=\sum\limits_{d=1}^n\mu(d)\sum\limits_{x=1}^{n/d}d(x)\sum\limits_{y=1}^{m/d}d(y)
\end{aligned}
\]
预处理函数 \(d(x),\mu(x)\) 的前缀和然后整除分块即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define int long long
using namespace std;
const int N = 50000;
int n, m, u[N + 9], a[N + 9], p[N], cnt, d[N + 9];
void prework()
{
u[1] = d[1] = 1;
for (int i = 2; i <= N; i++)
{
if (!a[i])
a[i] = i, p[++cnt] = i, u[i] = -1, d[i] = 2;
for (int j = 1; j <= cnt; j++)
{
if (p[j] > a[i] || p[j] > N / i)
break;
a[p[j] * i] = p[j];
if (i % p[j] != 0)
u[p[j] * i] = u[p[j]] * u[i],
d[p[j] * i] = d[p[j]] * d[i];
else
d[p[j] * i] = 2 * d[i] - d[i / p[j]];
}
}
for (int i = 1; i <= N; i++)
d[i] += d[i - 1], u[i] += u[i - 1];
}
signed main()
{
prework();
int T;
scanf("%lld", &T);
while (T--)
{
scanf("%lld %lld", &n, &m);
if (n > m) swap(n, m);
int ans = 0;
for (int i = 1; i <= n; i++)
{
int k = min(n / (n / i), m / (m / i));
ans += d[n / i] * d[m / i] * (u[k] - u[i - 1]);
i = k;
}
printf("%lld\n", ans);
}
}
标签:约数,lfloor,frac,limits,int,luogu,sum,rfloor,SDOI2015 来源: https://www.cnblogs.com/With-penguin/p/13715006.html