P1774 最接近神的人_NOI导刊2010提高(02)

P1774 最接近神的人_NOI导刊2010提高(02)


关于此题为什么可以使用求逆序对的方法来做

假设一个数\(a_i\),且前\(i-1\)个数已经成为单调增的数列。

我们要从前\(a_1\)\(a_{i-1}\)个数的有序队列中插入\(a_i\)

且只能使用类似冒泡排序的方法交换。

那么,插入这个数\(a_i\)需要交换的次数就是他的逆序对数。

有如下两种\(i\)的取值情况

---\(i==1\)\(i>1\)
逆序对数\(0\)可以推得

所以这种题就是求一个逆序对的个数,就\(\mathfrak{van}\)♂了

有道云markdown真难用

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
    long long val;
    int pos;
};
node data[600000];
bool compare(const node &a,const node &b)
{
    return a.val>b.val;
}
int bit[600000];
int num;
void insert(int pos,int val)
{
    while(pos<=num)
    {
        bit[pos]+=val;
        pos+=pos&(-pos);
    }
    return ;
}
long long  sum(int pos)
{
    long long res=0;
    while(pos)
    {
        res+=bit[pos];
        pos-=pos&(-pos);
    }
    return res;
}
int comp[600000];
int main()
{
    int n;
    scanf("%d",&n);
    num=n;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&data[i].val);
        data[i].pos=i;
    }
    sort(data+1,data+1+n,compare);
    long long now=-(1ll<<61);
    int ha=0;
    for(int i=1;i<=n;i++)
    {
        if(data[i].val!=now)
        {
            now=data[i].val;
            ha+=1;
        }
        comp[data[i].pos]=ha;
    }
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        ans+=sum(comp[i]-1);
        insert(comp[i],1);
    }
    printf("%lld",ans);
}

转载于:https://www.cnblogs.com/Lance1ot/p/9123498.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值