Codeforces Round 911 (Div. 2) D
Codeforces Round 911 (Div. 2) D
D. Small GCD
题意
定义\(f(a,b,c)\)为\(a,b,c\)中较小两个数的\(gcd\),给定数组\(a_{1...n}\),求
\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=j+1}^{n}f(a_i,a_j,a_k)
\end{aligned}
\]
题解
显然可以先排序,不会影响结果,排完序后\(a_k\)就是最大的,不会对\(gcd(a_i,a_j)\)产生影响.
所以当我们去枚举中间的\(a_j\)时,那么对于\(a_j\)来说,产生\((n-j)\times \sum\limits_{i = 1}^{n-1}gcd(a_i,a_j)\) 的贡献,其中\((n-j)\)是因为后面的\((n-j)\)个\(a_k\)都不会对\(gcd(a_i,a_j)\)产生影响,所以答案最终就是\(\sum\limits_{i=1}^{n-2}\sum\limits_{j=i+1}^{n-1}gcd(a_i,a_j) \times (n-j)\),而这样做的复杂度是\(O(n^2logm)\),其中\(m\)是\(\max\limits_{1\leq i\leq n}\{a_i\}\),而这样是会超时的.
到了这里,就该推出今天刚了解的欧拉反演了!
欧拉反演:即\(n\)的所有因子的欧拉函数和为n.
\sum\limits_{d|n}\varphi(d)=n
\end{aligned}
\]
将\(n\)换成其他:
gcd(i,j) = \sum\limits_{d|gcd(i,j)}\varphi(d) = \sum\limits_{d|i}\sum\limits_{d|j}\varphi(d)
\end{aligned}
\]
则:
\sum\limits_{i=1}^{n}gcd(i,n) = \sum\limits_{i=1}^{n}\sum\limits_{d|i}\sum\limits_{d|n}\varphi(d)=\sum\limits_{d|n}\sum\limits_{i=1}^{n}\sum\limits_{d|i}\varphi(d)=\sum\limits_{d|n}\frac{n}{d}\varphi(d)
\end{aligned}
\]
即:
\sum\limits_{i=1}^{n}gcd(i,n)=\sum\limits_{d|n}\frac{n}{d}\varphi(d)
\end{aligned}
\]
因为\(1\sim n\)里面含有因子为\(d\)一共有\(\frac{n}{d}\)个,所以这里就直接替换了,不过在这题里面从\(a_1 \sim a_{j-1}\)里面并不知道含有\(d\)作为因子数的有多少,所以我们需要维护\(a_1 \sim a_{j-1}\)中每个数的所有因子的个数\(cnt_d\),那么要计算\(1 \sim j-1\)的\(gcd\)则可以替换成:
\sum\limits_{i=1}^{j-1}gcd(a_i,a_j) = \sum\limits_{d|a_j}cnt_d\varphi(d)
\end{aligned}
\]
对于每一个数,先预处理出所含的约数,然后维护\(cnt_d\),就可以直接利用公式求和了.
ACcode:
#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
using namespace std;
using i64 = long long;
typedef pair<i64, i64> PII;
vector<int> euler_range(int n) {
vector<int> phi(n + 1), prime;
vector<bool> is_prime(n + 1, true);
is_prime[1] = 0, phi[1] = 1;
for (int i = 2; i <= n; i++) {
if (is_prime[i]) prime.push_back(i), phi[i] = i - 1;
for (int j = 0; j < (int)prime.size() && i * prime[j] <= n; j++) {
is_prime[i * prime[j]] = 0;
if (i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j] - 1);
else {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
}
}
return phi;
};
constexpr int N = 1E5;
auto phi = euler_range(N);
vector<int> fac[N + 1];
void solve() {
int n;
cin >> n;
vector<i64> a(n), b;
for (auto &i : a) cin >> i;
ranges::sort(a);
i64 ans = 0;
vector<int> cnt(N + 1);
for (int j = 0; j < n; j ++) {
for (auto d : fac[a[j]])
ans += 1ll * phi[d] * (n - j - 1) * cnt[d];
for (auto d : fac[a[j]])
cnt[d] ++;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
for (int i = 1; i <= N; i ++)
for (int j = 1; j <= N / i; j ++)
fac[i * j].push_back(i);
int T;
cin >> T;
while (T--) {
solve();
}
return 0;
}
参考资料:
欧拉反演 欧拉定理 - emptyset - 洛谷博客 (luogu.com.cn)
欧拉函数|(扩展)欧拉定理|欧拉反演 - Morning_Glory - 博客园 (cnblogs.com)
Codeforces Round 911 (Div. 2) A-E - 知乎 (zhihu.com)
积性函数 - YueTQ's Blog - 洛谷博客 (luogu.com.cn)
Codeforces Round 911 (Div. 2) D的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
- Codeforces Round #268 (Div. 2) ABCD
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
随机推荐
- pycharm中运行jupyter notebook
进入anaconda prompt,进入对应的虚拟环境 输入jupyter notebook,找到路径和token 这两个随便复制一个,注意是包括token也要复制到 然后打开pycharm,并建立一 ...
- 一文学完所有的Hive Sql(两万字最全详解)
Hive Sql 大全 本文基本涵盖了Hive日常使用的所有SQL,因为SQL太多,所以将SQL进行了如下分类: 一.DDL语句(数据定义语句): 对数据库的操作:包含创建.修改数据库 对数据表的操作 ...
- TCP,UDP,IP,数据链路层头部详解
UDP头部 可以看到UDP头部由(源端口).(目的端口).(长度)跟(校验和)组成,总共8字节. 源端口:发送方的端口号,16位,即2字节. 目的端口:接收方的端口号,16位,即2字节. 长度:头部+ ...
- Android7关机充电流程
2021-09-03:Android7关机充电流程 背景 为了修改关机充电中的显示效果,因此学习一下Android 7关机充电的流程是怎么样的. 以msm8909为例. [ 94.741021] ch ...
- 基于 SQLite 3 的 C 学习:1-开发流程 与 基本函数
背景 SQLite 是 一个 常用于 嵌入式平台的 轻量级的 关系型数据库. 我们已经介绍了 移植 SQLite 3 ,这一讲我们来介绍它的开发,这里仅仅涉及最基本的开发. 高级api:https:/ ...
- 缩小50%,Mini版T3/A40i核心板,让您的设备更小巧!
小尺寸核心板给用户带来何种价值? 创龙科技常收到用户对于小尺寸核心板的需求反馈,尤其在电力数据采集器.电力DTU.电力通讯管理机.运动控制器.工业HMI.工业网关等工业设备中. 小尺寸核心板3大优势将 ...
- SpringBoot整合Flyway数据库版本管理
项目结构 添加依赖 <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-co ...
- 测试人必会 K8S 操作之 Dashboard
在云计算和微服务架构的时代,Kubernetes (K8S) 已成为管理容器化应用的标准.然而,对于许多新手来说,K8S 的操作和管理常常显得复杂而神秘.特别是,当你第一次接触 K8S Dashboa ...
- 在windows双系统中,nginx配置虚拟域名
比如在ubuntu系统中,nginx配置了域名www.abc.com, 那么需要在终端 sudo vim /etc/hosts文件中配置域名,如下: 127.0.0.1 www.abc.com 即可访 ...
- 高程读后感(三)— JS对象实现继承的6种模式及其优缺点
目录 1.原型链 1.1.默认的原型 1.2.原型和实例的关系 1.3.原型链的问题 2.借用构造函数 2.1.传递参数 2.2.借用构造函数的问题 3.组合继承 4.原型式继承 5.寄生式继承 6. ...