「SOL」旧试题 (LOJ/SDOI)
数论+图论,妙不可言
# 题面
给定 \(A,B,C\),求:
\]
数据规模:\(A,B,C\le 2\times10^5\)。
# 解析
显然 \(A,B,C\) 三者等价,不妨设 \(A\) 是最大的
关于 \(\sigma_0\),有一个众所周知(比如我就不知道) 的结论:
\]
三个数也是一样的,
\]
于是直接代回我们要求的式子:
&\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^C\sum_{u\mid i}\sum_{v\mid j}\sum_{w\mid k}[u\bot v][v\bot w][w\bot u]\\
=&\sum_{u=1}^A\sum_{v=1}^B\sum_{w=1}^C[u\bot v][v\bot w][w\bot u]\left\lfloor\frac{A}{u}\right\rfloor\left\lfloor\frac{B}{v}\right\rfloor\left\lfloor\frac{C}{w}\right\rfloor
\end{aligned}
\]
记 \([a,b]\) 为 \(a, b\) 的最小公倍数。两数互质的条件可以进行反演:
\sum_{a}\sum_{b}\sum_{c}\mu(a)\mu(b)\mu(c)\sum_{[a,b]\mid u}\left\lfloor\frac{A}{u}\right\rfloor\sum_{[b,c]\mid v}\left\lfloor\frac{B}{v}\right\rfloor\sum_{[c,a]\mid w}\left\lfloor\frac{C}{w}\right\rfloor
\end{aligned}
\]
定义 \(f_b(a)\) 如下:
\]
可以 \(O(A\ln A)\) 预处理出 \(f_A(x), f_B(x), f_C(x)\),于是要求的答案就是
\]
但是我们发现这一波推导过后并没有什么用,直接算还是 \(O(A^3)\) 的。只是可以进行一些剪枝?
- \(\mu(a),\mu(b),\mu(c)\) 都必须非零,这样可以去掉很多无用的枚举;
- \(\max\big\{[a,b],[b,c],[c,a]\big\}\le A\),好像也可以减掉一些枚举。
这些剪枝足够吗?如果仍然三重 for 循环枚举,这样剪枝过后还是过不了。但是注意到这两个限制,第二个限制与两个变量相关,类似于图上的边。
- 条件一限制了图上的点的 \(\mu\) 非零;
- 条件二表示,若 \([a,b]\le A\),则图上存在 \((A,B)\) 这条无向边。
恰巧的是,我们计算的是一个三元组,体现在图上就是一个三元环!
记 \(M\) 为图的边数,我们可以用下面的方法 \(O(M\sqrt{M})\) 地枚举所有三元环:
- 统计每个点的度数,记作 \(deg_u\);
- 给边定向,由度数大的点指向度数小的,若度数相等,则编号大的指向编号小的(编号小指向编号大也无所谓,反正要求二元组 \((\deg_u,u)\) 的大小比较唯一且具有传递性);
- 枚举点 \(u\):
- 标记 \(u\) 连出的所有点 \(v\);
- 枚举 \(u\) 连出的点 \(v\):
- 枚举 \(v\) 连出的点 \(w\),若 \(w\) 有标记,则找到三元环。
三元环计数正确性、时间复杂度的证明
根据边定向的规则,因为数对 $(deg_u, u)$ 的大小关系具有传递性且唯一确定,所以定向后的图一定是 DAG。
这意味着三元环一定是由 $u\to v\to w$ 和 $u\to w$ 构成的。且根据我们的枚举方式,这样的三元环仅能在枚举 $u$ 时计算到。所以计数不重不漏,正确性有保证。
时间复杂度的证明类似分块。首先,标记点的时间复杂度为 $O(M)$,因为每条边只会遍历一次,不是复杂度的瓶颈。
然后关注枚举的 $u\to v\to w$ 的中心点 $v$:
- 若 $deg_v\le\sqrt{M}$,则 $w$ 只有 $O(\sqrt{M})$ 个,$(u,v)$ 最多 $O(M)$ 个,则所有此类点 $v$ 的复杂度为 $O(M\sqrt{M})$;
- 若 $deg_v\gt\sqrt{M}$,因为 $u$ 连向 $v$,则 $deg_u\ge deg_v\gt\sqrt{M}$,这样的 $u$ 只有 $O(\sqrt{M})$ 个,而 $(v,w)$ 仅有 $O(M)$ 个;则所有此类 $v$ 点的复杂度也为 $O(M\sqrt{M})$。
总复杂度 $O(M\sqrt{M})$。
回到这道题上来,我们就是要枚举图上的一个三元环然后计算答案。那么这个图的边数多大呢?打个表发现 \(O(M\sqrt{M})\) 能过……(反正我不会证)
于是按上述方法枚举即可。
注意实际上枚举的不止有三元环,还存在 \(a=b\) 甚至是 \(a=b=c\) 的情况,不过这两种都可以直接暴力枚举,不是很重要。
# 源代码
/*Lucky_Glass*/
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define con(typ) const typ &
typedef long long llong;
typedef pair<int, int> pii;
inline int rin(int &r) {
int b = 1, c = getchar(); r = 0;
while ( c < '0' || '9' < c ) b = c == '-' ? -1 : b, c = getchar();
while ( '0' <= c && c <= '9' ) r = (r * 10) + (c ^ '0'), c = getchar();
return r *= b;
}
inline void write(con(int) w) {
if ( w > 9 ) write(w / 10), putchar((w % 10) ^ '0');
else if ( w < 0 ) putchar('-'), write(-w);
else putchar(w ^ '0');
}
const int N = 2e5 + 10, M = 2e6, MOD = 1e9 + 7;
inline int iGCD(con(int) a, con(int) b) {return b ? iGCD(b, a % b) : a;}
int na, nb, nc, ncas, nprm, nedg;
int mu[N], prm[N], deg[N], edg[M][3], tag[N];
llong fa[N], fb[N], fc[N];
bool vis[N];
vector<pii> lnk[N];
void init() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if ( !vis[i] ) prm[++nprm] = i, mu[i] = -1;
for (int j = 1; j <= nprm && prm[j] * i < N; j++) {
vis[i * prm[j]] = true;
if ( i % prm[j] == 0 ) break;
mu[i * prm[j]] = -mu[i];
}
}
}
void proc(con(int) n, llong *arrf) {
for (int i = 1; i <= n; i++) {
arrf[i] = 0;
for (int j = i; j <= n; j += i)
arrf[i] += n / j;
}
}
int main() {
init();
rin(ncas);
while ( ncas-- ) {
rin(na), rin(nb), rin(nc);
int mx = max(na, max(nb, nc)), mn = min(na, min(nb, nc));
fill(fa, fa + mx + 1, 0);
fill(fb, fb + mx + 1, 0);
fill(fc, fc + mx + 1, 0);
proc(na, fa), proc(nb, fb), proc(nc, fc);
llong ans = 0;
// Part 1
for (int i = 1; i <= mn; i++)
ans += mu[i] * fa[i] * fb[i] * fc[i]; // mu[i] ^ 3 = mu[i]
// Part 2
fill(deg, deg + 1 + mx, 0), nedg = 0;
for (int g = 1; g <= mx; g++)
for (int i = 1; i * g <= mx; i++) if ( mu[i * g] )
for (int j = i + 1; 1ll * i * j * g <= mx; j++)
if ( mu[j * g] && iGCD(i, j) == 1 ) {
int lcm = i * j * g, ig = i * g, jg = j * g;
// iij
ans += mu[jg] * (fa[ig] * fb[lcm] * fc[lcm]
+ fa[lcm] * fb[ig] * fc[lcm]
+ fa[lcm] * fb[lcm] * fc[ig]);
// ijj
ans += mu[ig] * (fa[jg] * fb[lcm] * fc[lcm]
+ fa[lcm] * fb[jg] * fc[lcm]
+ fa[lcm] * fb[lcm] * fc[jg]);
// add edges at the same time :)
deg[ig]++, deg[jg]++;
edg[++nedg][0] = ig, edg[nedg][1] = jg;
edg[nedg][2] = lcm;
}
// Part 3
for (int i = 1; i <= mx; i++) lnk[i].clear();
for (int i = 1; i <= nedg; i++)
if ( deg[edg[i][0]] > deg[edg[i][1]]
|| (deg[edg[i][0]] == deg[edg[i][1]] && edg[i][0] < edg[i][1]) )
lnk[edg[i][0]].push_back(make_pair(edg[i][1], edg[i][2]));
else lnk[edg[i][1]].push_back(make_pair(edg[i][0], edg[i][2]));
for (int u = 1; u <= mx; u++) if ( mu[u] ) {
for (int i = 0, ii = (int)lnk[u].size(); i < ii; i++)
tag[lnk[u][i].first] = lnk[u][i].second;
for (int i = 0, ii = (int)lnk[u].size(); i < ii; i++) {
int v = lnk[u][i].first, luv = lnk[u][i].second;
for (int j = 0, _j = (int)lnk[v].size(); j < _j; j++)
if ( tag[lnk[v][j].first] ) {
int w = lnk[v][j].first, lvw = lnk[v][j].second,
luw = tag[w];
ans += mu[u] * mu[v] * mu[w] * (
fa[luv] * fb[luw] * fc[lvw]
+ fa[luv] * fb[lvw] * fc[luw]
+ fa[luw] * fb[luv] * fc[lvw]
+ fa[luw] * fb[lvw] * fc[luv]
+ fa[lvw] * fb[luv] * fc[luw]
+ fa[lvw] * fb[luw] * fc[luv]
);
}
}
for (int i = 0, ii = (int)lnk[u].size(); i < ii; i++)
tag[lnk[u][i].first] = 0;
}
write(int(ans % MOD)), putchar('\n');
}
return 0;
}
THE END
Thanks for reading!
怎知晓 有人 玩世不恭掩愁肠
取次花丛懒望 等剪烛西窗
怎知晓 有人 独为异客在异乡
嘴上逞强终不敢 举头看月光
——《从前有个衔玉教》By 星葵/鲜洋芋/溱绫西陌
> Link 【0412乐正绫诞生祭】从前有个衔玉教-Bilibili
「SOL」旧试题 (LOJ/SDOI)的更多相关文章
- loj#2565. 「SDOI2018」旧试题(反演 三元环计数)
题意 题目链接 Sol 神仙反演题.在洛谷上疯狂被卡常 Orz shadowice #include<bits/stdc++.h> #define Pair pair<int, in ...
- LOJ2476. 「2018 集训队互测 Day 3」蒜头的奖杯 & LOJ2565. 「SDOI2018」旧试题(莫比乌斯反演)
题目链接 LOJ2476:https://loj.ac/problem/2476 LOJ2565:https://loj.ac/problem/2565 题解 参考照搬了 wxh 的博客. 为了方便, ...
- [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC
[LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...
- 「NOI2018」归程
「NOI2018」归程 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 >\(1\) 个节点. \(m\) 条边的无向连通图(节点的编号从 \( ...
- 2090. 「ZJOI2016」旅行者 分治,最短路
2090. 「ZJOI2016」旅行者 链接 loj 思路 \((l,mid)(mid+1,r)\).考虑跨过mid的贡献. 假设选的中间那条线的点为gzy,贡献为\(dis(x,gzy)+dis(g ...
- 【LOJ】#3088. 「GXOI / GZOI2019」旧词
LOJ#3088. 「GXOI / GZOI2019」旧词 不懂啊5e4感觉有点小 就是离线询问,在每个x上挂上y的询问 然后树剖,每个节点维护轻儿子中已经被加入的点的个数个数乘上\(dep[u]^{ ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
随机推荐
- Ubuntu下安装Node.js+ThreeJs
以具有sudo特权的用户身份运行以下命令,以下载并执行NodeSource安装脚本 curl -sL https://deb.nodesource.com/setup_16.x | sudo -E b ...
- docker学习(dockerfile打jar包为镜像)
docker打包jar为docker镜像 1.使用Dockerfile打镜像 将spring boot应用打包成jar包放置在/app/applcation路径中 编写dockerfile文件,内容参 ...
- springboot启动日志:Multiple Spring Data modules found, entering strict repository configuration mode
问题描述 最近启动springboot项目的时候,发现有一条日志:Multiple Spring Data modules found, entering strict repository conf ...
- MySQL 学习(四)并集查询
联合查询,它是用 union 关键字把多条 select 语句的查询结果合并为一个结果集.纵向合并的前提是被合并的结果集的字段数量.顺序和数据类型必须完全一致.字段名不一样的情况下,会将第一个结果集的 ...
- ROS-安装与开发速记
参考教程: B站视频(感谢赵老师):https://www.bilibili.com/video/BV1Ci4y1L7ZZ?p=14&spm_id_from=pageDriver 课程文件:h ...
- vue 定时器 定时刷新页面 定时请求接口
data(){ return{ intervalId:null, } }, methods:{ // 定时刷新数据函数 dataRefreh() { // 计时器正在进行中,退出函数 if (this ...
- chatgpt 的训练数据时间内容估计
I noticed that the data you quoted is dated September 2021, but it's already 2023. I apologize for t ...
- 【阿里云ACP】-01(阿里云综述、弹性计算)
课程能力 课程范围 ECS 磁盘 实例 磁盘 快照 镜像 网络 安全组 AS 伸缩组 伸缩配置 伸缩规则 伸缩活动 伸缩触发任务 伸缩模式 冷却时间 SLB 定义 实现原理 支持的协议 绘画保持 健康 ...
- onActivityResult 解耦 不需要一层一层的写
public abstract class AbsShareMessageTemplates implements IShareMessageTemplates { public final stat ...
- QT如何安装?
Qt安装教程 OLD HELPS <oldhelps@126.com > 目录 Qt安装教程 下载 注册.登录 接受验证邮件 安装 下载 从https://download.qt.io/n ...