codevs 4163 hzwer与逆序对

本文介绍了一种求解逆序对数量的有效算法,并通过树状数组实现。该算法适用于处理大规模数据集,如含有上百万个元素的数列。文章提供了一个完整的C++代码示例,展示了如何通过读取输入数据、排序以及使用树状数组来计算逆序对的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 黄金 Gold
 
 
 
题目描述  Description

hzwer在研究逆序对。

对于数列{a},如果有序数对(I,j)满足:i<j,a[i]>a[j],则(i,j)是一对逆序对。

给定一个数列{a},求逆序对个数。

输入数据较大,请使用scanf代替cin读入。

*为防卡评测,时限调低至1s

 

输入描述  Input Description

第一行一个数n,表示{a}有n个元素。

接下来n个数,描述{a}。

 

输出描述  Output Description

一个数,表示逆序对个数。

 

样例输入  Sample Input

5

3 1 5 2 4

 

样例输出  Sample Output

4

数据范围及提示  Data Size & Hint

对于10%数据,1<=n<=100.

对于20%数据,1<=n<=10000.

对于30%数据,1<=n<=100000.

对于100%数据,1<=n<=1000000,1<=a[i]<=10^8.

tips:我没有想故意卡你们时限。一点这样的意思都没有。你们不要听风就是雨……

 

比赛已结束 详细解析见题解

分类标签 Tags 

 

连树状数组求逆序对我都不会写了,,好弱啊

关于怎么实现,推荐一篇博客

http://www.cnblogs.com/xiongmao-cpp/p/5043340.html

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define LL long long 
 7 #define lb(x)    ((x)&(-x))
 8 using namespace std;
 9 const int MAXN=40000001;
10 inline int read()
11 {
12     char c=getchar();int x=0,f=1;
13     while(c<'0'||c>'9')    {if(c=='-')    f=-1;c=getchar();}
14     while(c>='0'&&c<='9')    x=x*10+c-48,c=getchar();return x*f;
15 }
16 int n;
17 int tree[MAXN];
18 int a[MAXN];
19 int data[MAXN];
20 inline void Point_Add(int pos,int val)
21 {
22     while(pos<=n)
23     {
24         tree[pos]+=val;
25         pos+=lb(pos);
26     }
27 }
28 inline int Interval_Sum(int pos)
29 {
30     int ans=0;
31     while(pos)
32     {
33         ans+=tree[pos];
34         pos-=lb(pos);
35     }
36     return ans;
37 }
38 int main()
39 {
40     n=read();LL ans=0;
41     for(int i=1;i<=n;i++)    a[i]=read(),data[i]=a[i];
42     int num=unique(data,data+n+1)-data-1;
43     sort(data+1,data+n+1);
44     for(int i=1;i<=n;i++)    a[i]=lower_bound(data+1,data+num+1,a[i])-data;
45     for(int i=1;i<=n;i++)
46     {
47         Point_Add(a[i],1);
48         ans+=i-Interval_Sum(a[i]);
49     }
50     printf("%lld",ans);
51     return 0;
52 }

 

转载于:https://www.cnblogs.com/zwfymqz/p/7709659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值