• P1908 逆序对(树状数组解法)


    题目描述

    猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。

    最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aja_i>a_jai​>aj​ 且 i<ji<ji<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。

    Update:数据已加强。

    输入格式

    第一行,一个数 nnn,表示序列中有 nnn个数。

    第二行 nnn 个数,表示给定的序列。序列中每个数字不超过 10910^9109。

    输出格式

    输出序列中逆序对的数目。

    输入输出样例

    输入 #1 复制

    6

    5 4 2 6 3 1

    输出 #1 复制

    11

    这个题可以用线段树写,但树状数组写起来更优雅一些。数据加强后可以作为树状数组+离散化的板子题了。看到数据范围我们知道常规的桶肯定是不行的,1e9直接MLE,那么需要离散化一下。这里我用的是结构体存储原数和其初始位置,然后对结构体数组从小到大sort一遍。此时开辟一个新的数组rank。比较关键的部分是:

    for(i=1;i<=n;i++)

    {

           rank[p[i].x]=i;

    }

    rank数组也相当一个桶,只不过桶的大小不必为1e9了,只需5e5即可。这样得到的新的rank数组实际上和原数组是等价的,只不过数的绝对大小变成了相对大小。然后利用树状数组处理。但这样其实有一个问题,就是数据可能是重复的。解决方法有2:一是用stable_sort排序,外加cmp函数里取等号;二是cmp函数中如果两个结构体数值相等,那么按照位置大小排序。这样的话即使两个数相等,也会使得分配后的大小能确保不会对逆序数的计算产生影响。

    #include <bits/stdc++.h>
    using namespace std;
    int ans=0,n,i;
    int t[500005],rank[500005];
    struct point
    {
        int num;
        int x;
    }p[500005];
    bool cmp(point a, point b)
    {
        if(a.num != b.num) return a.num < b.num;
        return a.x < b.x;
    }
    void add(int x, int y)
    {
        for( ; x <= n; x += x & (-x)) t[x] += y;
    }
    int ask(int x)
    {
        int ans=0;
        for(; x; x -= x & -x) ans += t[x]; 
        return ans;
    }
    int main()
    {
        cin>>n;
        int i;
        long long cnt=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p[i].num); 
            p[i].x=i;//位置 
        } 
        sort(p + 1, p + n + 1, cmp);//按照原数排序
        for(i=1;i<=n;i++)
        {
            rank[p[i].x]=i;
        }
    
        for(i=1;i<=n;i++)
        {
            cnt += 0ll + ask(n) - ask(rank[i]);
            add(rank[i], 1);
        } 
        cout<<cnt;
        return 0; 
    } 
  • 相关阅读:
    linux服务器上无root权限如何安装nodejs?
    Jupyter按tab键无法补全,而且报错TypeError: __init__() got an unexpected keyword argument 'column'的解决办法
    通过损失函数优化提高训练速度、准确性和数据利用率
    华为诺亚AutoML框架-Vega:(2) 代码结构
    华为诺亚实验室AutoML框架-Vega:(1) 介绍
    AutoML: A survey of the state-of-the-art综述期刊论文免费下载
    安装Docker 图形界面管理工具 -- Portainer
    Dockfile 编写示例(将 jar 制作成容器)
    Docker 常用命令集
    云服务器CentOS安装Docker
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13246920.html
Copyright © 2020-2023  润新知