题目链接:http://poj.org/problem?id=2299

求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法。

归并排序:

#include<cstdio>
#include<iostream>
using namespace std;
#define max 500002
int arr[max],b[max];//b[]为临时序列,arr[]为待排序数列,结果在arr[]中
int tp[max];
long long cnt=;//总逆序数
void Merge(int a[],int start,int mid,int end){
int i =start,j=mid+,k=start;
while(i<=mid&&j<=end){
if(a[i]<=a[j]){
cnt+=j-mid-;
b[k++]=a[i++];
}else{
cnt+=j-k;
b[k++]=a[j++];
}
}
while(i<=mid){
cnt+=end-mid;
b[k++]=a[i++];
}
while(j<=end){
b[k++]=a[j++];
}
for(int i=start;i<=end;i++){
a[i]=b[i];
}
}
void MergeSort(int a[], int start,int end){
if(start<end){
int mid=(start+end)/;
MergeSort(a,start,mid);
MergeSort(a,mid+,end);
Merge(a,start,mid,end);
}
}
int main(){
int n;
while(~scanf("%d",&n)&&n){
for(int i=;i<n;i++){
scanf("%d",&arr[i]);
}
cnt=;
MergeSort(arr,,n-);
printf("%I64d\n",cnt/);
}
return ;
}

  

树状数组:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
using namespace std;
const int MAX = ;
struct data{
int id,val;
}num[MAX];
int n, C[MAX];
bool cmp(data a, data b){
return a.val>b.val;
}
void add(int i){
while(i<=n){
C[i]+=;
i+=lowbit(i);
}
}
long long sum(int i){
long long ans = ;
while(i>){
ans+=C[i];
i-=lowbit(i);
}
return ans;
} int main(){
while(scanf("%d",&n)&&n){
memset(C,,sizeof(C));
for(int i=;i<n;i++){
num[i].id=i+;
scanf("%d",&num[i].val);
}
sort(num,num+n,cmp);//离散化,将数组按降序排序,再求下标的逆序数,下标的逆序数与值逆序数相等
long long ans = ;
for(int i=;i<n;i++){
ans+=sum(num[i].id-);//求在i前面比第i个数大的数的个数
add(num[i].id);
}
printf("%I64d\n", ans);
}
return ;
}

 线段树( 以HDU1394 Minimum Inversion Number为例):

#include<iostream>
#include<cstdio>
#include<cstdlib>#include<algorithm>
const int INF = 0x3F3F3F3F;
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define N 5008
int sum[N<<], a[N];
inline void pushUp(int rt){
sum[rt] = sum[rt << ] + sum[rt << | ];
} int query(int a, int b, int l, int r, int rt){
if(a <= l && b >= r){
return sum[rt];
}
int m=(l + r) >> ;
int ret=;
if(a <= m){
ret += query(a, b, lson);
}
if(b > m){
ret += query(a, b, rson);
}
return ret;
}
void update(int x, int val, int l, int r, int rt){
if(l == r){
sum[rt] = val;
}else{
int m = (l + r)/;
if(x <= m){
update(x, val, lson);
}else{
update(x, val, rson);
}
pushUp(rt);
}
} int main(){
int n;
while(~scanf("%d", &n)){
memset(sum, , sizeof(sum));
int ans = ;
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
a[i]++;
ans += query(a[i] + , n, , n , );
update(a[i], , , n, );
}
int tp = ans;
for(int i = ; i < n - ; i++){
tp += n - * a[i] + ;
ans = min(ans , tp);
}
printf("%d\n",ans);
}
}

POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树的更多相关文章

  1. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  2. POJ 1195 Mobile phones (二维树状数组或线段树)

    偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...

  3. st表、树状数组与线段树 笔记与思路整理

    已更新(2/3):st表.树状数组 st表.树状数组与线段树是三种比较高级的数据结构,大多数操作时间复杂度为O(log n),用来处理一些RMQ问题或类似的数列区间处理问题. 一.ST表(Sparse ...

  4. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  5. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  6. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  7. 【BZOJ3196】二逼平衡树(树状数组,线段树)

    [BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...

  8. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  9. HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)

    Jam's problem again Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

随机推荐

  1. php使用文件缓存

    使用php读取mysql中的数据很简单,数据量不大的时候,mysql的性能还是不错的.但是有些查询可能比较耗时,这时可以把查询出的结果,缓存起来,减轻mysql的查询压力. 缓存的方法有几种:使用me ...

  2. jQuery数组($.each,$.grep,$.map,$.merge,$.inArray,$.unique,$.makeArray)处理函数详解

    1. $.each(array, [callback]) 遍历[常用] 解释: 不同于例遍jQuery对象的$().each()方法,此方法可用于例遍任何对象.回调函数拥有两个参数:第一个为对象的成员 ...

  3. 【转】ArrayList其实就那么一回事儿之源码浅析

    转自:http://www.cnblogs.com/dongying/p/4013271.html?utm_source=tuicool&utm_medium=referral ArrayLi ...

  4. spring + myBatis 常见错误:SQL语法错误

    在程序运行时,有时候会出现如下错误: 这个错误通常是你的sqlmapper.xml中sql语句语法有错误.所以请仔细查看你sql语句是否正确,比如{#id}这样写就会报上述错误,其实应该#{id}这样 ...

  5. 在本地计算机无法启动MYSQL服务错误1067进程意外终止

    在本地计算机无法启动MYSQL服务错误1067进程意外终止 这种情况一般是my.ini文件配置出错了, 你可以删除系统目录下的my.ini文件, 把下面的内容重新写入my.ini文件试试, 要适当地改 ...

  6. ACM/ICPC 之 SPFA-兑换货币(POJ1860)

    //水题-SPFA解法 //套汇是指兑换货币后能使本金上升 //给定本金货币编号,货币间的汇率和手续费,求能否套汇成功 //Time:16Ms Memory:200K #include<iost ...

  7. JAVA thread0.interrupt()方法

    interrupt()只是改变中断状态而已,interrupt()不会中断一个正在运行的线程.这一方法实际上完成的是,给受阻塞的线程抛出一个中断信号,这样受阻线程就得以退出阻塞的状态. 更确切的说,如 ...

  8. java 基础第一季

    1. i安装jdk ii 配置环境变量:JAVA_HOME 配置jdk的安装路径 path            配置命令文件的位置 bin目录的安装路径 PATH_HOME 配置库文件的位置   l ...

  9. JS判断客户端是手机还是PC的2个代码(转)

    转载自:http://www.jb51.net/article/48939.htm Javascript 判断客户端是否为 PC 还是手持设备,有时候项目中需要用到,很方便的检测,源生的哦,方法一共有 ...

  10. WP开发资源

    wp开发:连续两次点击返回键退出程序的设计: http://hi.baidu.com/youngytj/item/6be317719cc371306cc37ce4 X http://www.cnblo ...