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为还需要的蜡烛数, ...
随机推荐
- 记一次反向代理过滤sql注入
公司有一php系统,由于该系统是购买的,并且没人懂php,无法通过修改代码过滤sql注入问题 代码如下: public class Program { public static void Main( ...
- Linux中的inode
inode是什么 一个文件由两部分组成:元信息和数据. 在Linux中,inode包含文件的元信息,具体来说有以下内容: Size 文件的字节数 Uid 文件拥有者的User ID Gid 文件的Gr ...
- Kubernetes容器生命周期 —— 钩子函数详解(postStart、preStop)
1.概述 容器生命周期钩子(Container Lifecycle Hooks)监听容器生命周期的特定事件,并在事件发生时执行已注册的回调函数. 钩子函数能够感知自身生命周期中的事件,并在相应的时刻到 ...
- 日常Bug排查-改表时读数据不一致
前言 日常Bug排查系列都是一些简单Bug的排查.笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材. Bug现场 线上连续两天出现NP异常,而且都是凌晨低峰期才出现,在凌晨的流量远没有白天高 ...
- [好物推荐] Rime的86五笔输入法配置
一个比较好用的Rime五笔输入法配置文件, 个人已经使用很多年了. 官网: https://github.com/KyleBing/rime-wubi86-jidian 安装方式: /home/xxx ...
- 【价格全面下调】一片含税79元,双核A7@1.2GHz,-40℃~85℃真工业级!
自9个月前,创龙科技全志T113-i核心板(SOM-TLT113)推出之后,受到广大工业用户的高度关注,且超过300家企业已选用创龙科技T113-i核心板用于终端产品开发. 为了让更多用户轻松选择T1 ...
- Unity中正面视图的相机最大距离定位
问题背景: Unity中在场景中有这样的需求,就是俯视整个场景或者平视整个场景.这种情况下场景中物体长宽比不一定和相机视口长宽比一致,要保证所有的物体都在视口内,并且距离不能太远,,所以处理起来需要点 ...
- rust项目中通过log4rs将日志写入文件
java项目中使用最广泛的日志系统应该是log4j(2)了.如果你也是一个Java程序员,可能在写rust的时候会想怎么能顺手地平移日志编写习惯到rust中来. log4rs就是干这个的.从名字就能看 ...
- C++使用gnuplot-cpp库绘制图像
最近想要对一些时变的变量进行可视化,搜索来搜索去选择了使用gnuplot这个工具. sudo apt-get install gnuplot sudo apt-get install gnuplot- ...
- 解读MySQL 8.0数据字典缓存管理机制
背景介绍 MySQL的数据字典(Data Dictionary,简称DD),用于存储数据库的元数据信息,它在8.0版本中被重新设计和实现,通过将所有DD数据唯一地持久化到InnoDB存储引擎的DD t ...