和式的变换以及几道例题
和式的变换与推导例题
规则
\(\sum\limits_{k\in K} ca_k=c\sum\limits_{k\in K}a_k\)
\(\sum\limits_{k\in K}(a_k+b_k)=\sum\limits_{k\in K}a_k+\sum\limits_{k\in K}b_k\)
\(\sum\limits_{k\in K}a_k=\sum\limits_{p(k)\in K}a_{p(k)}\) 交换律。\(p(k)\) 是下标排列
和式的变换技术
1. 替换条件式
\(\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{d|\gcd(i,j)}d=\sum\limits_{i=1}^n\sum\limits^m_{j=1}\sum\limits_{d=1}^n[d|i][d|j]d\)
暴力枚举
2. 替换指标变量
\(\sum\limits_{i=1}^n\sum\limits^m_{j=1}[\gcd(i,j)=k]=\sum\limits^n_{ik=1}\sum\limits^m_{jk=1}[\gcd(ik,jk)=k]=\sum\limits^n_{ik=1}\sum\limits^m_{jk=1}[\gcd(i,j)=1]\)
具体证明……
3. 交换求和次序
\(\sum\limits^n_{i=1}\sum\limits^m_{j=1}A(i)B(i)=\sum\limits^m_{j=1}\sum\limits^n_{i=1}A(i)B(i)\)
4. 分离变量
\(\sum\limits^n_{i=1}\sum\limits^m_{j=1}A(i)B(i)=\sum\limits^n_{i=1}A(i)\sum\limits^m_{j=1}B(i)\)
感性理解即可
例题
1#P3455 [POI2007]ZAP-Queries
题意:给出 \(n,m,k\),求 \(\sum\limits_{i=1}^n\sum\limits^m_{j=1}[\gcd(i,j)=k]\)。数据规模 \(1\le k\le n,m\le 5*10^4,T=5*10^4\)
用到莫比乌斯函数的性质 \(\sum\limits_{d|n}\mu(d)=[n=1]\)
此处应用: \([\gcd(i,j)=1]=\sum\limits_{d|\gcd(i,j)}\mu(d)\)
那么
\(\sum\limits_{i=1}^n\sum\limits^m_{j=1}[\gcd(i,j)=1]\\ = \sum\limits_{i=1}^n\sum\limits^m_{j=1}\sum\limits_{d|\gcd(i,j)}\mu(d)\\ =\sum\limits_{i=1}^n\sum\limits^m_{j=1}\sum\limits_{d=1}^n[d|i][d|j]\mu(d)\\ =\sum\limits^n_{d=1}\mu(d)\sum\limits_{i=1}^n[d|i]\sum\limits^m_{j=1}[d|j]\\ =\sum\limits^n_{d=1}\mu(d) \lfloor\dfrac{n}{d}\rfloor \lfloor\dfrac{m}{d}\rfloor\)
算莫比乌斯函数的前缀和,后两项是数论分块。整除分块 \(\sum\limits^n_{i=1}f(i)\lfloor\dfrac{n}{i}\rfloor\)
那么现在再来看复杂情况:
\(\sum\limits_{i=1}^n\sum\limits^m_{j=1}[\gcd(i,j)=k]\\ = \sum\limits_{ik=1}^n\sum\limits^m_{jk=1}[\gcd(ik,jk)=k]\\ =\sum\limits_{i=1}^{\lfloor\dfrac{n}{k}\rfloor}\sum\limits^{\lfloor\dfrac{m}{k}\rfloor}_{j=1}[\gcd(i,j)=1]\)
同理导出莫比乌斯函数,最终
\(\sum\limits_{d=1}^{\lfloor\dfrac{n}{k}\rfloor}\mu(d)\lfloor\dfrac{n}{kd}\rfloor\lfloor\dfrac{m}{kd}\rfloor\)
莫比乌斯函数用线性筛即可。
2#P2257 YY的GCD
题意:给出 \(n,m\) 求 \(\sum\limits^n_{i=1}\sum\limits^m_{j=1}[\gcd(i,j)\in prime]\)
\(\begin{aligned} & \sum_{i=1}^{n} \sum_{j=1}^{m}[\operatorname{gcd}(i, j) \in \text { prim }] \\ = & \sum_{i=1}^{n} \sum_{j=1}^{m} \sum_{k=1}^{n}[\operatorname{gcd}(i, j)=k][k \in \text { prim }] \\ = & \sum_{k=1}^{n} \sum_{i=1}^{\left|\frac{n}{k}\right|} \sum_{j=1}^{\left|\frac{m}{k}\right|}[\operatorname{gcd}(i, j)=1][k \in \text { prim }] \\ = & \sum_{k=1}^{n} \sum_{i=1}^{\left|\frac{n}{k}\right|} \sum_{j=1}^{\left|\frac{m}{k}\right|} \sum_{d \mid \operatorname{gcd}(i, j)} \mu(d)[k \in \text { prim }] \\ = & \sum_{k=1}^{n} \sum_{i=1}^{\left|\frac{n}{k}\right|} \sum_{j=1}^{\left|\frac{m}{k}\right|} \sum_{d=1}^{\left|\frac{n}{k}\right|}[d \mid i][d \mid j] \mu(d)[k \in \text { prim }] \\ = & \sum_{k=1}^{n} \sum_{d=1}^{\left|\frac{n}{k}\right|} \mu(d) \sum_{i=1}^{\left|\frac{n}{k}\right|}[d \mid i] \sum_{j=1}^{\left|\frac{m}{k}\right|}[d \mid j][k \in \text { prim }] \\ =& \sum\limits^n_{k=1}\sum\limits^{\lfloor\frac{n}{k}\rfloor}_{d=1}\mu(d)\left\lfloor\dfrac{n}{kd}\right\rfloor\left\lfloor \dfrac{m}{kd}\right\rfloor\end{aligned}\)
发现无法整除分块,分母是两个变量
令 \(T=kd\),则 \(d=T/k\)
\(=\sum\limits_{k=1}^{n}\sum\limits_{\frac{T}{k}}^{\left\lfloor\frac{n}{k}\right\rfloor}\mu(\dfrac{T}{k})\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor\ [k\in prime] \\ =\sum\limits_{k=1}^{n}\sum\limits_{T=1}^{n}\mu(\dfrac{T}{k})\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor\ [k\in prime] \\ =\sum\limits_{T=1}^{n}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor\sum\limits_{k=1}^{n}\mu(\dfrac{T}{k})\ [k\in prime]\\ =\sum\limits_{T=1}^{n}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor\sum\limits_{k\in prime}\mu(\dfrac{T}{k})\)
设 \(F(T)=\sum\limits_{k\in prime}\mu(\dfrac{T}k)\)
则原式化为:
\(\sum\limits^n_{T=1}F(T)\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}T\right\rfloor\)
\(F(T)\) 需要预处理
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
const int N = 10000010;
int vis[N], p[N], mu[N], cnt;
int F[N];
void init()
{
mu[1] = 1;
for (int i = 2; i < N; i++)
{
if (!vis[i])
p[++cnt] = i, mu[i] = -1;
for (int j = 1; i * p[j] < N; j++)
{
vis[i * p[j]] = 1;
if (i % p[j] == 0)
break;
mu[i * p[j]] = -mu[i];
}
}
for (int i = 1; i <= cnt; i++)
for (int j = p[i]; j < N; j += p[i])
// j 和 pi 只能是整数倍
F[j] += mu[j / p[i]];
for (int i = 1; i < N; i++)
F[i] += F[i - 1];
}
LL calc(int n, int m)
{
if (n > m)
swap(n, m);
LL ans = 0;
for (int l = 1, r; l <= n; l = r + 1)
{
r = min(n / (n / l), m / (m / l));
ans += 1ll * (F[r] - F[l - 1]) * (n / l) * (m / l);
}
return ans;
}
int main()
{
init();
int n, m, T;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
printf("%lld\n", calc(n, m));
}
}
3#P3327 [SDOI2015] 约数个数和
题意:设 \(d(x)\) 为 \(x\) 的约数个数。给定 \(n,m\) 求 \(\sum\limits^n_{i=1}\sum\limits^m_{j=1}d(ij)\), \(T\) 组询问,\(T,n,m\le 5*10^4\)
结论:\(d(ij)=\sum\limits_{x|i}\sum\limits_{y|j}[\gcd(x,y)=1]\) 证明参考,和数学一本通莫比乌斯反演
证明看不懂,背下来吧。
最后化为 \(\sum\limits^n_{d=1}\mu(d)F(\left\lfloor\dfrac{n}{d}\right\rfloor)F(\left\lfloor\dfrac{m}{d}\right\rfloor)\)
那么预处理 \(\mu\) 和 \(F\),预处理 \(F\) 需要用到一次数论分块,计算结果时还需要用到一次数论分块。
#include <bits/stdc++.h>
#define rei register int
#define ll long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define rep(i, s, n, c) for (register int i = s; i <= n; i+=c)
#define repd(i, s, n, c) for (register int i = s; i >= n; i-=c)
#define CHECK cout<<"WALKED"<<endl;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
#define pb push_back
#define ls id<<1
#define rs id<<1|1
const int INF = INT_MAX;
long long binpow(long long a, long long b, ll mod){long long res = 1; while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1; } return res;}
using namespace std;
const int maxn = 50005;
int vis[maxn], p[maxn], mu[maxn], cnt;
ll F[maxn];
void init()
{
mu[1]=1;
rep (i, 2, maxn - 1, 1) {
if (!vis[i]) {
p[++cnt] = i;
mu[i]= -1;
}
for (int j = 1; i * p[j] < maxn; j++) {
vis[i * p[j]] = 1;
if (i % p[j] == 0) break;
mu[i * p[j]] = -mu[i];
}
}
rep (i, 1, maxn - 1, 1) {
mu[i] += mu[i - 1]; // mobius prefixsum
}
rep (i, 1, maxn - 1, 1) {
int r;
rep(l, 1, i, -l + r + 1) {
r = (i / (i / l));
F[i] += 1ll * (r - l + 1) * (i / l);
}
}
}
ll cc(int n, int m)
{
if (n > m) swap(n, m);
ll ans = 0;
int r;
rep (l, 1, n, -l + r + 1) {
r = min(n / (n / l), m / (m / l));
ans += (mu[r] - mu[l - 1]) * F[n/l] * F[m/l];
// 下标整除也可以分块
}
return ans;
}
int main()
{
init();
int n, m, T = read();
while (T--) {
n = read(), m = read();
printf("%lld\n", cc(n,m));
}
return 0;
}
最后整理一下
待做题目:P2522