题目链接

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定一个1-N的排列A1, A2, ... AN,如果Ai和Aj满足i < j且Ai > Aj,我们就称(Ai, Aj)是一个逆序对。

求A1, A2 ... AN中所有逆序对的数目。

输入

第一行包含一个整数N。

第二行包含N个两两不同整数A1, A2, ... AN。(1 <= Ai <= N)

对于60%的数据 1 <= N <= 1000

对于100%的数据 1 <= N <= 100000

输出

一个整数代表答案

样例输入
5
3 2 4 5 1
样例输出
5
 求逆序对,两种方法,一个是用树形数组做,一个是用归并排序做。两种都试了一遍,有一个地方比较坑就是数组类型必须是long long。不然会WA,题目却没有明显信息说要long long。。这个地方可以说是很坏坏了。
 
树形数组ac代码:
 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<iomanip>
using namespace std; //1524 : 逆序对
const int maxn = 1e5 + ;
int n;
long long a[maxn], b[maxn];
int lowbit(int i)
{
return i&-i;
}
void update(int i)
{
while (i <= n)
{
b[i]++;
i += lowbit(i);
}
}
long long sum(int i)
{
long long cnt = ;
while (i)
{
cnt += b[i];
i -= lowbit(i);
}
return cnt;
}
int main()
{
cin >> n;
for (int i = ;i <= n;i++)
{
cin >> a[i];
}
memset(b, , sizeof(b));
long long res = ;
for (int i = n;i >= ;i--)
{
update(a[i]);
res += sum(a[i] - );
}
cout << res << endl;
return ;
}

树形数组这个东西还是比较有趣的。这个算法可以说是比较天才了。

具体的树形数组详解可以看这个博主的http://blog.csdn.net/ljd4305/article/details/10101535

归并排序的ac代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<iomanip>
using namespace std; //1524 : 逆序对
const int maxn = 1e5 + ;
int n;
long long a[maxn],b[maxn];
long long cnt; void merge_sort(long long * a, int l, int r)
{
int mid = (l + r) >> ;
int m = l, n = mid + ;
int pos = l;
while (m<=mid&&n<=r)
{
if (a[m] < a[n])
{
b[pos++] = a[m++];
}
else
{
b[pos++] = a[n++];
cnt+=mid-m+;
}
} while (m <= mid) b[pos++] = a[m++];
while (n <= r) b[pos++] = a[n++];
for (int i = l;i <= r;i++)
a[i] = b[i];
}
void merge(long long * a, int l, int r)
{
if (l >= r) return;
int mid = (l + r) >>;
merge(a, l, mid);
merge(a, mid+, r);
merge_sort(a, l, r);
} int main()
{
cnt = ;
cin >> n;
for (int i = ;i <= n;i++)
{
cin >> a[i];
}
merge(a, , n);
cout << cnt << endl;
return ;
}

归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。在合并的过程中(设l<=i<=mid,mid+1<=j<=h),当a[i]<=a[j]时,并不产生逆序数;当a[i]>a[j]时,在前半部分中比a[i]大的数都比a[j]大,将a[j]放在a[i]前面的话,逆序数要加上mid+1-i。因此,可以在归并排序中的合并过程中计算逆序数。

可以参考http://blog.csdn.net/acdreamers/article/details/16849761

hihocoder1524的更多相关文章

  1. 树形数组 java

    2^k求法 int lowbit(int x) { return x&(-x); } lowbit()的返回值就是 2^k 次方的值. 基本树形数组的模板 import java.util.* ...

随机推荐

  1. ThreadLocal详解,ThreadLocal源码分析,ThreadLocal图解

    本文脉路: 概念阐释 ---->  原理图解  ------> 源码分析 ------>  思路整理  ----> 其他补充. 一.概念阐述. ThreadLocal 是一个为 ...

  2. checkbox选中相关问题总结

    html: <input type="checkbox" name="fruit" id="apple">苹果 <inpu ...

  3. vue-app开发入门

    vue的中文文档在这里 1. 简单地引用vue.js 使用vue框架最简单的方式就是写一个HTML页面然后引用vue.js啦. 使用<script> 标签就可以将vue.js导入并且使用它 ...

  4. Python学习(四) —— 编码

    一.枚举 enumerate,for i in enumerate(可迭代对象),返回元组,内容是(序列号,可迭代的每一个元素)        for i,j in enumerate(可迭代对象,开 ...

  5. Python 多进程multiprocessing

    一.python多线程其实在底层来说只是单线程,因此python多线程也称为假线程,之所以用多线程的意义是因为线程不停的切换这样比串行还是要快很多.python多线程中只要涉及到io或者sleep就会 ...

  6. Flask--第三个例子,写一个接口,该接口返回html前端页面,模板的使用

     将接口数据返回至html前端页面有两种方法 方法一: 1 @app.route('/index',methods=['get']) 2 def open_index(): 3 page=open(' ...

  7. sql 跨服务器查询

    创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvlogin ...

  8. 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组

    题目描述: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明:初始化 nums1 和 nums2 的元素数量分别为 m ...

  9. nginx+uwsgi启动Django项目

    1.安装项目环境 系统环境:ubuntu16.04 python环境:python3.5.2 Django版本:django1.11.7 nginx环境:nginx_1.10.3 虚拟环境:virtu ...

  10. Noj - 在线强化训练1

      1445 A 求n个整数的和   1564 B 判断一个数是否是完全数   1011 C 判素数(Prime number)   1566 D 输入一组整数,找出最小值   1200 E 判断三角 ...