【题解】CF1780F-Three Chairs

题目(cf)

题目(luogu)

题目大意

给定长度为 n ( 3 ≤ n ≤ 3 × 1 0 5 ) n(3\le n\le 3\times 10^5) n(3n3×105) 的数组 a ( 1 ≤ a i ≤ 3 × 1 0 5 ) a(1\le a_i\le 3\times 10^5) a(1ai3×105),其中的元素互不相同。问有多少三元组满足最大数与最小数互质。两个三元组不同当且仅当存在数 x x x 出现在三元组 A A A 中而不出现在三元组 B B B 中。

题解

容易发现数组 a a a 的顺序对答案没有影响。为了方便统计答案,我们人为地给它安排顺序,也就是对 a a a 数组排序。

显然,当确定了三元组中最大值和最小值后,中间值可以随意选,只需要满足它位于最大最小值之间。也就是说,当最大值为 a i a_i ai 而最小值为 a j a_j aj(显然 j < i j<i j<i)时,中间值有 i − j − 1 i-j-1 ij1 种取值。

易得

a n s = ∑ g c d ( a i , a j ) = 1 , j < i ( i − j − 1 ) ans=\sum\limits_{gcd(a_i,a_j)=1,j<i}(i-j-1) ans=gcd(ai,aj)=1,j<i(ij1)

对于每个 i i i 考虑其贡献,有

a n s = ∑ i = 1 n ∑ g c d ( a i , a j ) ( i − j − 1 ) = ∑ i = 1 n ∑ j = 1 i − 1 ( i − j − 1 ) [ g c d ( a i , a j ) = 1 ] ans=\sum\limits_{i=1}^{n}\sum\limits_{gcd(a_i,a_j)}(i - j - 1)\\ =\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i-1}(i - j - 1)[gcd(a_i, a_j)=1] ans=i=1ngcd(ai,aj)(ij1)=i=1nj=1i1(ij1)[gcd(ai,aj)=1]

以下是莫反技巧推导。

a n s = ∑ i = 1 n ∑ j = 1 i − 1 ( i − j − 1 ) [ g c d ( a i , a j ) = 1 ] = ∑ i = 1 n ∑ j = 1 i − 1 ( i − j − 1 ) ∑ k ∣ g c d ( a i , a j ) μ ( k ) ans=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i-1}(i - j - 1)[gcd(a_i, a_j)=1]\\ =\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i-1}(i - j - 1)\sum\limits_{k|gcd(a_i, a_j)}\mu(k) ans=i=1nj=1i1(ij1)[gcd(ai,aj)=1]=i=1nj=1i1(ij1)kgcd(ai,aj)μ(k)

考虑将 μ \mu μ 提到最前面,变换枚举对象,枚举 d = g c d ( a i , a j ) d=gcd(a_i,a_j) d=gcd(ai,aj)

a n s = ∑ d = 1 a n μ ( d ) ∑ d ∣ a i ∑ d ∣ a j , j < i ( i − j − 1 ) ans=\sum\limits_{d=1}^{a_n}\mu(d)\sum\limits_{d|a_i}\sum\limits_{d|a_j,j<i}(i-j-1) ans=d=1anμ(d)daidaj,j<i(ij1)

考虑分离 i i i j j j.

a n s = ∑ d = 1 a n μ ( d ) ∑ d ∣ a i ( ∑ d ∣ a j , j < i ( i − 1 ) − ∑ d ∣ a j , j < i j ) ans=\sum\limits_{d=1}^{a_n}\mu(d)\sum\limits_{d|a_i}\left(\sum\limits_{d|a_j,j<i}(i-1)-\sum\limits_{d|a_j,j<i}j\right) ans=d=1anμ(d)dai daj,j<i(i1)daj,j<ij

整理出容易解决的式子:

a n s = ∑ d = 1 a n μ ( d ) ∑ d ∣ a i ( ( i − 1 ) ∑ j = 1 i − 1 [ d ∣ a j ] − ∑ d ∣ a j , j < i j ) ans=\sum\limits_{d=1}^{a_n}\mu(d)\sum\limits_{d|a_i}\left((i-1)\sum\limits_{j=1}^{i-1}[d|a_j]-\sum\limits_{d|a_j,j<i}j\right) ans=d=1anμ(d)dai (i1)j=1i1[daj]daj,j<ij

μ ( d ) \mu(d) μ(d) 可以欧拉筛线性预处理。

对于 d d d a i a_i ai,可以直接枚举,时间复杂度为 O ( n + n 2 + n 3 + ⋯ + n n ) = O ( n × ( 1 + 1 2 + 1 3 + ⋯ + n n ) ) = O ( n ln ⁡ n ) O(n+\dfrac n 2+\dfrac n 3+\cdots+\dfrac n n)=O(n\times (1+\dfrac 1 2+\dfrac 1 3+\cdots+\dfrac n n))=O(n\ln n) O(n+2n+3n++nn)=O(n×(1+21+31++nn))=O(nlnn).

关于 j j j 的项,可以在枚举 i i i 的过程中累加统计,因为 j j j 必定小于 i i i,也就是说之前其实已经遍历过 j j j 了。具体见代码。

总的时间复杂度是 O ( n ln ⁡ n ) O(n\ln n) O(nlnn).

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 300005;
int n, a[N], mu[N], pri[N], cnt = 0, vis[N], b[N];
LL ans = 0;
void init() {
    mu[1] = 1;
    for (int i = 2; i < N; i++) {
        if (!vis[i]) pri[++cnt] = i, mu[i] = -1;
        for (int j = 1; j <= cnt && i * pri[j] < N; j++) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
            mu[i * pri[j]] = -mu[i];
        }
    }
}
int main() {
    init();//莫比乌斯函数线性筛
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) b[a[i]] = i;//b[i]表示值为i的元素在数组中出现的位置
    for (int d = 1; d <= a[n]; d++) {//枚举d
        LL sum = 0, s1 = 0, s2 = 0;//sum统计后面的一大串式子,s1统计前i-1个数有多少出现在数组中且整除d,s2统计出现在数组中且整除d的元素的位置(下标)和
        for (int i = d; i <= a[n]; i += d)//枚举值,值在数组中的位置是b[i]
            if (b[i])//数组中有i这个数
                sum += 1ll * (b[i] - 1) * s1 - s2, s1++, s2 += b[i];//维护
        ans += sum * mu[d];
    }
    printf("%lld", ans);
    return 0;
}

END

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值