小苯的逆序对

小苯的逆序对

题目描述

小苯有一个长度为 n 的排列 p。他很想知道这个排列中有多少个逆序对满足互素。

形式化的,有多少个满足 (i<j)(ai>aj)gcd(ai,aj)=1(i,j) 对。

输入描述:

输入包含两行。

第一行一个正整数 n(1n2×105)。表示排列的长度。

第二行 n 个正整数 pi(1pin) 表示排列 p,保证 1n 的每个正整数出现且恰好仅出现一次。

输出描述:

输出包含一行一个整数,表示排列 p 的互素逆序对个数。

示例1

输入

5
5 4 3 2 1

输出

9

示例2

输入

8
1 3 8 7 2 4 6 5

输出

8

示例3

输入

2
1 2

输出

0

备注:

其中 gcd(x,y) 表示 x,y 的最大公因数,例如 gcd(12,16)=4,gcd(1,4)=1

 

解题思路

  D. Counting Rhyme 的变形。现在变成求满足 gcd(ai,aj)=1 的逆序对 (ai,aj),ai>aj,i<j 的数量。

  定义 fi 表示 gcd 恰好等于 i 的逆序对的数量,先求出所有 gcdi 的倍数的逆序对的数量,记作 s。做法是先把 a 中所有是 i 的倍数的元素按原本顺序选出来,然后对选出来的元素用树状数组求逆序对数量。最后根据容斥的思想,有 fi=sf2if3ifnii。倒叙枚举依次求出 fi 即可。

  最后答案就是 f1

  AC 代码如下,时间复杂度为 O(nn+nlogn)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

int n;
vector<int> g[N];
LL f[N];
int tr[N];

int lowbit(int x) {
    return x & -x;
}

void add(int x, int c) {
    for (int i = x; i <= n; i += lowbit(i)) {
        tr[i] += c;
    }
}

int query(int x) {
    int ret = 0;
    for (int i = x; i; i -= lowbit(i)) {
        ret += tr[i];
    }
    return ret;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        int x;
        scanf("%d", &x);
        for (int j = 1; j * j <= x; j++) {
            if (x % j == 0) {
                g[j].push_back(x);
                if (x / j != j) g[x / j].push_back(x);
            }
        }
    }
    for (int i = n; i; i--) {
        LL s = 0;
        for (int j = 0; j < g[i].size(); j++) {
            s += j - query(g[i][j]);
            add(g[i][j], 1);
        }
        for (int j = i + i; j <= n; j += i) {
            s -= f[j];
        }
        f[i] = s;
        for (int j = 0; j < g[i].size(); j++) {
            add(g[i][j], -1);
        }
    }
    printf("%lld", f[1]);
    
    return 0;
}

 

参考资料

  题解 | #牛客小白月赛87 #:https://blog.nowcoder.net/n/2804f9f3cb1e4590b1d97bef99b8f28f?

posted @   onlyblues  阅读(120)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2023-02-16 台阶-Nim游戏
2022-02-16 二分求解最值问题例题
Web Analytics
点击右上角即可分享
微信分享提示