P1908 逆序对

题目链接:P1908 逆序对

图片说明
图片说明

离散化:

  • 离散化(Discretization),把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。(转自网络)

    个人理解:

  • 对于一些数据,我们不需要知道它本身值的大小,而需要这些数据互相对应的位置,那么采用离散化进行数据处理。
  • 而逆序对正好符合这一特点,例如(2000,100,300000)可以转换为(2,1,3)

离散化代码如下:

bool cmp(Node a,Node b){
    if(a.value != b.value) return a.value < b.value;
    return a.point < b.point;
}
n = read();
for(int i = 1; i <= n; i ++ ){
        node[i].value = read();
        node[i].point = i;
}
sort(node + 1, node + n + 1,cmp);
for(int i = 1; i <= n; i ++ ){
    b[node[i].point] = i;
}
  • Q1:怎么统计第 i 个数会与第1~ i−1个数构成多少个逆序对呢?
    考虑根据值来建树状数组 , 初始树状数组为全 0。现在按照序列从左到右将数据的值对应的位置的数加一,代表又有一个数出现,因此,循环到第i项的时候,前面i-1项已经加入到树状数组中,那么逆序对的数量为总个数i- 它前面所有比它小的个数(前缀和sum(x)),即i - sum(x);
  • Q2:用a[i]来建立树状数组,空间不够用怎么办?
    这启发我们对数据离散化,先将数据排序,再用 1 ~ n分别对应 n 个数表示它们的相对大小,对新的序列建树状数组空间就够了

代码如下:

#include<bits/stdc++.h>

using namespace std;

#define  mm(a,x) memset(a,x,sizeof a)
#define  mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)

const int N = 5e5 + 10;

int read(){
    char x = getchar();
    int ans = 0;
    for(;x < '0' || x >'9' ; x = getchar());
    for(;x >= '0' && x <= '9' ; x = getchar()){
        ans *= 10;
        ans += (x - '0');
    }
    return ans;
}

struct Node{
    int value,point;
}node[N];

int n;
int b[N],tr[N];

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

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

bool cmp(Node a,Node b){
    if(a.value != b.value) return a.value < b.value;
    return a.point < b.point;
}

int main() {
    n = read();
    for(int i = 1; i <= n; i ++ ){
        node[i].value = read();
        node[i].point = i;
    }
    sort(node + 1, node + n + 1,cmp);
    for(int i = 1; i <= n; i ++ ){
        b[node[i].point] = i;
    }
    ll ans = 0;
    for(int i = 1; i <= n; i ++ ){
        add(b[i],1);
        ans += i - sum(b[i]);
    }    
    cout<<ans;
    return 0;
}

感谢学无止境大佬提供的思路

全部评论

相关推荐

2024-12-11 14:09
已编辑
中国海洋大学 数值策划
点赞 评论 收藏
分享
正在干活结果人事过来找我,说我被裁了,还说要裁一半,一些没转正的先踢出去…&nbsp;真是牛逼现在的公司,怪不得越做越小。上个月初提交的转正申请,我老大也同意了,我真以为我转正了,结果人事跟我说我老大不知道这些,好吧那你们瞒着呗真是逆天…&nbsp;又要开始找工作了,现在工作哪里这么好找,还有这么多公司喜欢这种操作,坑我们应届生真服了👿
CoderEcho:看你的主页,你好像是有点内向,不怎么说话?我之前实习也是这样的,hr和主管也是用我太内向导致的主管看不到头,工作习惯不好,不适合他们这样的原因把我实习劝退,但是公司肯定有公司的问题,因为去年没一个实习转正的,连社招生都劝退。倒也不是替公司说话,只是一些建议,公司内部裁员肯定是公司的问题,只是积极主动(或者领导眼中积极主动)的人未来一定会有更多机会,刚被劝退的时候基本上秋招已经结束,但是1月份的时候还是上岸啦,并且面试时我说出了我对积极主动的理解也是加分的一点。祝你继续加油往前走,大厂经历+985学历,结果一定不会差的啦
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务