【莫比乌斯反演】C - LCMs - AGC038

题目链接(https://atcoder.jp/contests/agc038/tasks/agc038_c)

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : \(700\) points

Problem Statement

We have an integer sequence of length \(N\): \(A_0,A_1,\cdots,A_{N-1}\).Find the following sum (\(\mathrm{lcm}(a, b)\) denotes the least common multiple of \(a\)and \(b\)):\(\sum_{i=0}^{N-2} \sum_{j=i+1}^{N-1} \mathrm{lcm}(A_i,A_j)\)

Since the answer may be enormous, compute it modulo \(998244353\).

Constraints

\(1 \leq N \leq200000\)

\(1 \leq A_i \leq 1000000\)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

\(N\)

\(A_0\ A_1\ \cdots\ A_{N-1}\)

Output

Print the sum modulo \(998244353\).

Sample Input 1

3 2 4 6

Sample Output 1

22

\(\mathrm{lcm}(2,4)+\mathrm{lcm}(2,6)+\mathrm{lcm}(4,6)=4+6+12=22\).

Sample Input 2

8 1 2 3 4 6 8 12 12

Sample Output 2

313

Sample Input 3

10 356822 296174 484500 710640 518322 888250 259161 609120 592348 713644

Sample Output 3

353891724

题意

给定长度为\(N\)的序列\(A_1,A_2,...,A_N\),求\(\sum_{i = 0}^{N-2}\sum_{j=i+1}^{N-1}lcm(A_i.A_j)\),模\(998244353\)

\((1\leq N\leq 2*10^5,1\leq A_i\leq 10^6)\)

思路

(笔记)

众所周知\(lcm(a,b) == (a * b) / gcd(a,b)\)

设答案为\(ans\),则可以由\(\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}lcm(A_i,A_j) = 2 * ans + \sum_{i=0}^NA_i\)

间接知道\(ans\)大小

\(\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}lcm(A_i,A_j)\)

\(=\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}(A_i*A_j)/gcd(A_i,A_j)\)

\(=\sum_{d=1}^{L}1/d\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}(A_i*A_j)[gcd(A_i,A_j) = d]\)

\(f(d)=\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}(A_i*A_j)[gcd(A_i,A_j) = d]\)

\(f(d)\)作倍数和,\(i,j\)相当于是一样的所以后面作平方

\(g(d)=\sum_{d|d'}f(d')=(\sum_{i=0}^{N-1}A_i[d|A_i])^2\)

\(f(d)=\sum_{d|d'}μ(d'/d)g(d')=\sum_{d|d'}μ(d'/d)(\sum_{i=0}^{N-1}A_i[d|A_i])^2\)

最终得到求和式

\(\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}lcm(A_i,A_j)=\sum_{d=1}^L1/d\sum_{d|d'}μ(d'/d)(\sum_{i=0}^{N-1}A_i[d'|A_i])^2\)

在这里,对于任意的\(d\)的这样的一个求和式\(h(d)=\sum_{d|n}f(d)g(n/d)\),可以通过枚举因子或者枚举倍数来求得\(h(n)\),复杂度\(O(nlogn)\)

然后就可以一步步求求和式:

对于求和式,第一项是求所有的\(A_i\)\(d'\)的倍数的求和, \((\sum_{i=0}^{N-1}A_i[d'|A_i])\),就可以把这里的求和看作\(h(d') = \sum_{i = 0}^{N-1}A_i[d'|A_i]\),把\(A_i\)用一个数组存起来,对这个数组进行倍数和,可以用\(nlogn\)的复杂度求取\(h(d')\),用桶数组\(pos[]\)优化方便累加,即\(h(d') = \sum_{d'|i}pos_i\)

然后就可以来求\(\sum_{d|d'}μ(d'/d)h(d')^2\),又是类似于倍数和的一种形式,可以用\(nlogn\)的复杂度求取\(\sum_{d|d'}μ(d'/d)\),即\(h'(d) = \sum_{d|d'}μ(d'/d)\)这样

最后可以用\(O(n)\)的复杂度求取\(\sum_{d=1}^L1/d*h'(d)\)

总复杂度\(O(LlogL+N),L=maxA_i\)

(嘤嘤嘤,被笨死惹,不想敲注释,名字和思路里的变量都对应的上吧)

AC代码

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
#define endl '\n'
const int N = 1e6 + 100;
const int mod = 998244353;
const double pi = acos(-1.0);
typedef long long ll;
using namespace std;
int n;
int mx;
int a[N],pos[N];
int h1[N], h2[N];
int miu[N];
int prime[N], num;
bool vis[N];
int quickpow(int a, int b) {
	int res = 1;
	while (b > 0) {
		if (b & 1) res = res * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return res;
}
int getinv(int a) {
	return quickpow(a, mod - 2);
}
void init() {
	mx = 0;
	for (int i = 1; i <= n; i++) {
		a[i] = 0;
	}
	return;
}
void solve() {
	init();
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		pos[a[i]] = (pos[a[i]] + a[i]) % mod;
		mx = max(mx, a[i]);
	}

	miu[1] = 1;
	for (int i = 2; i <= 1e6; i++)
	{
		if (!vis[i]) prime[++num] = i, miu[i] = -1;
		for (int j = 1; j <= num && i * prime[j] <= 1e6; j++)
		{
			vis[i * prime[j]] = 1;
			if (i % prime[j] == 0) break;
			miu[i * prime[j]] = -miu[i];
		}
	}

	for (int d = 1; d <= 1e6; d++)
	{
		int d_inv = getinv(d);
		for (int dd = d; dd <= 1e6; dd += d)
		{
			h1[d] = (h1[d] + pos[dd]) % mod;
			h2[dd] = (h2[dd] + miu[dd / d] * d_inv % mod + mod) % mod;
		}
	}

	int ans = 0;
	for (int d = 1; d <= mx; d++) {
		ans = (ans + h1[d] * h1[d] % mod * h2[d] % mod) % mod;
	}

	ans = ((ans - h1[1]) % mod + mod) % mod;

	cout << ans * getinv(2) % mod;
	return;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	while (cin >> n) {
		solve();
	}
	return 0;
}
posted @ 2021-11-05 17:07  TomiokapEace  阅读(88)  评论(0)    收藏  举报