ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

51nod3121 小陶与杠铃片

2021-11-02 21:34:10  阅读:174  来源: 互联网

标签:杠铃 树状 int 51nod3121 数组 小陶 define


3121 小陶与杠铃片

小陶在举重队负责后勤工作。举重队的训练场中有一个区域一排码放了n片杠铃片,每天运动员们训练完之后会将杠铃片放回,之后小陶需要重新整理杠铃片的顺序,使它们由轻到重依次排好。由于杠铃片很重,小陶每次只能选两片相邻的杠铃片,交换它们的位置。现在小陶想知道,这一天他至少需要交换多少次才能整理完毕?

已知n<=200000,0<=杠铃片重量<=200000。

输入

第一行一个正整数n,表示有n片杠铃片;
第二行n个整数,表示运动员们放回后每片杠铃片依次的重量。

输出

输出一个整数,表示小陶至少交换的次数。

数据范围

对于30%的数据: n<=5000
对于60%的数据: n<=30000
对于100%的数据: n<=200000,0<=杠铃片重量<=200000

输入样例

10
16808 75250 50074 143659 108931 11273 27545 50879 177924 37710

输出样例

20

解析:

树状数组求逆序对

对于序列中的每个数a_{j},如果我们能设法快速找出有多少个a_{j},满足i<j且a_{i}>a_{j}就好了 

其实也可以先找满足i<j且a_{i}< = a_{j}的个数cnt,那么j-cnt就是我们上面要求的数量

怎么找呢?

我们可以用树状数组去维护这样一个数组: num[i]表示权值为i的数的个数。

那么我们依次枚举每个数并将其加入树状数组,在需要统计满足i<j且a_{i}< = a_{j}的个数时,我们使得树状数组里加入了a_{1},a_{2},...a_{j-1},然后在树状数组中统计num_{1}+num_{2}+...+num_{aj}即可,这是一段区间和,而且是一段前缀和,非常容易求出。

放代码:

#include<bits/stdc++.h>
using namespace std; 
#define lowbit(i) (i & -i)
#define MX 200000
#define N 200020
int n;
int a[N], C[N];
void add(int x, int c) {
    for (int i = x; i <= MX; i += lowbit(i))
        C[i] += c;
}
int ask(int x) {
    int ret = 0;
    for (int i = x; i; i -= lowbit(i))
        ret += C[i];
    return ret;
}
long long ans;
int main() {
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++) {
        ans += (i - 1) - ask(a[i]);
        add(a[i], 1);
    }
    cout << ans << endl;
}

 

 

标签:杠铃,树状,int,51nod3121,数组,小陶,define
来源: https://blog.csdn.net/ZCH1901/article/details/121109420

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有