51Nod 1019 逆序数
来源:互联网 发布:linux命令存储 编辑:程序博客网 时间:2024/05/22 13:39
题意:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。
解题思路:树状数组求逆序数.很经典的题目,因为树状数组下标是从1开始的,所以用数组存的时候下标也要从1开始。然后给一个数组排序,再二分查找在排序后的数组中的位置。举个例子:2 4 3 1,排序后就是1 2 3 4,然后原数组中第一个元素2在第二个位置,4在第四个位置,然后找逆序就是该位置之后的元素个数,因为已经排好序了嘛,后面的元素肯定比前面的大,如果在该元素出现之前,已经有比它大的元素出现了,那么就是一个逆序啊
代码:
#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <vector>#include <set>#include <map>#include <queue>using namespace std;const int maxn=50000+5;int bit[maxn];int n;int a[maxn],b[maxn];int lowbit(int x){ return (x&-x);}int sum(int i){ int s=0; while(i>0) { s+=bit[i]; i-=lowbit(i); } return s;}void add(int i,int x){ while(i<=n) { bit[i]+=x; i+=lowbit(i); }}void init(){ memset(bit,0,sizeof(bit)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b));}int main(){ while(scanf("%d",&n)==1) { init(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i]=a[i]; } sort(a+1,a+n+1); int ans=0; for(int i=1;i<=n;i++) { int pos=lower_bound(a+1,a+n+1,b[i])-a; add(pos,1); ans+=sum(n)-sum(pos); } printf("%d\n",ans); } return 0;}
阅读全文
0 0
- 51nod 1019 逆序数
- 51nod 1019 逆序数
- [51nod]1019 逆序数
- 51nod 1019 逆序数
- 51nod 1019 逆序数
- 51nod 1019 逆序数
- 51nod 1019 逆序数
- 51nod 1019逆序数
- 51Nod--1019 逆序数
- 51Nod 1019 逆序数
- 51Nod-1019-逆序数
- 51Nod 1019 逆序数
- 51nod 1019 逆序数
- 51Nod 1019 逆序数
- 51Nod 逆序数
- 51nod逆序数
- 逆序数 51Nod
- 逆序数 51Nod
- 实验四 Linux系统管理
- 博弈汇总
- 基于opencv+Dlib的面部合成(Face Morph)
- eclipse快捷键总结
- 文献阅读相关-MODELING AND SOLVING THE TRAIN TIMETABLING PROBLEM-OR-2002-Caprara
- 51Nod 1019 逆序数
- Ubuntu下Sql Server的安装
- http://my.csdn.net/my/favorite
- 三角形的判定
- python 打印函数调用栈
- 华为机试在线训练108题:密码验证合格程序
- ps学习第2天,打开文件 改变大小
- request.getQueryString()是什么意思
- 移位