和式的变换以及几道例题
和式的变换与推导例题
规则
交换律。 是下标排列
和式的变换技术
1. 替换条件式
暴力枚举
2. 替换指标变量
具体证明……
3. 交换求和次序
4. 分离变量
感性理解即可
例题
1#P3455 [POI2007]ZAP-Queries
题意:给出 ,求 。数据规模
用到莫比乌斯函数的性质
此处应用:
那么
算莫比乌斯函数的前缀和,后两项是数论分块。整除分块
那么现在再来看复杂情况:
同理导出莫比乌斯函数,最终
莫比乌斯函数用线性筛即可。
2#P2257 YY的GCD
题意:给出 求
发现无法整除分块,分母是两个变量
令 ,则
设
则原式化为:
需要预处理
#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] 约数个数和
题意:设 为 的约数个数。给定 求 , 组询问,
结论: 证明参考,和数学一本通莫比乌斯反演
证明看不懂,背下来吧。
最后化为
那么预处理 和 ,预处理 需要用到一次数论分块,计算结果时还需要用到一次数论分块。
#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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现