求数组逆序对

思路:类似归并排序算法,在合并已经有序的相邻子数组的时候,计算前面数组相对于后面数组的逆序对数,整个递归过程可以算出所有逆序对#include <stdio.h>
void merge(int A[], int front, int middle, int end, int &count)
{
    if (front >= end) return;
    int i = front;
    int j = middle + 1;
    int k = 0;
    int *p = new int[end - front + 1];
    while (i <= middle && j <= end) {
        if (A[i] < A[j]) {
            p[k++] = A[i++];
        } else {
            count += middle - i + 1;
            p[k++] = A[j++];
        }
    }
    if (j <= end) while (j <= end) {
        p[k++] = A[j++];
        count += middle - i + 1;
    }
    if (i <= middle) while (i <= middle) p[k++] = A[i++];
    printf("front:%d end:%d :", front, end);
    for (int i = 0; i < k; ++i) {
        printf("%d ", p[i]);
        A[front + i] = p[i];
    }
    printf("\n");

    delete [] p;
}
void merge_sort(int A[], int front, int end, int &count)
{
    if (front >= end) return;
    int middle = (front + end) / 2;
    merge_sort(A, front, middle, count);
    merge_sort(A, middle + 1, end, count);
    merge(A, front, middle, end, count);
}

int main()
{
    int count = 0;
    int rand[] = {3,1,5,23,2,32,56,76,65,34,2,2,333,1,0};
    merge_sort(rand, 0, 4,  count);
    for (int i = 0; i < 5; ++i) {
        printf("%d ", rand[i]);
    }
    printf("\n");
    printf("%d\n", count);
    return 0;
}

求数组逆序对,布布扣,bubuko.com

时间: 2024-10-11 17:44:46

求数组逆序对的相关文章

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

Bzoj 2789: [Poi2012]Letters 树状数组,逆序对

2789: [Poi2012]Letters Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 185[Submit][Status][Discuss] Description 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. Input 第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度

【树状数组逆序对】USACO.2011JAN-Above the median

[题意] 给出一串数字,问中位数大于等于X的连续子串有几个.(这里如果有偶数个数,定义为偏大的那一个而非中间取平均) [思路] 下面的数据规模也小于原题,所以要改成__int64才行.没找到测试数据,自己编的几组.简单来说读入每个数,大于等于中位数设为1,小于设为-1,前i个数的和建立一个树状数组,求逆序对. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorit

Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度.每列火柴中相

总结之---树状数组+逆序对问题。

咳咳,这个图必须要的.... 首先,当有一个数组a数量非常大的时候,我们可能改变某个a[i]的值,要求a[n]的和,全部加起来,无疑是要O(n)的时间复杂度. 但是如果n非常大时,O(n)时间复杂度肯定要跪,所以,怎么办的,用神奇的树状数组. 树状数组代码简单,但是非常强大!更令人兴奋的是,它的时间复杂度值需要O(logn)!!! 好了,首先要的东西是把上图的c[n]表示出来,该怎么弄呢,代码如下: int lowbit(int t) { return t&(-t); } 这个代码,简单到爆,但

HDU 1394Minimum Inversion Number 数状数组 逆序对数量和

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18543    Accepted Submission(s): 11246 Problem Description The inversion number of a given number sequence a1, a2, ..., a

题解 SP4226 【MSE06H - Japan】(树状数组+逆序对)

原OJ提交点这里 这道题一开始让我很雾...... 不过 思路其实非常清晰:如果i<j a[i].x<a[j].x a[i].y>a[j].y 那么就会产生一个交点 大家画个图就出来了 具体操作也很好实现: 定义一个结构体 x升序排列 当x相同就y升序排列 按照我们的排序方式 把a[i].y踢出来跑树状数组求逆序对就可以了 附上AC代码 #include<cstdio> #include<iostream> #include<cmath> #inclu

AcWing:241. 楼兰图腾(树状数组逆序对)

在完成了分配任务之后,西部314来到了楼兰古城的西部. 相传很久以前这片土地上(比楼兰古城还早)生活着两个部落,一个部落崇拜尖刀(‘V’),一个部落崇拜铁锹(‘∧’),他们分别用V和∧的形状来代表各自部落的图腾. 西部314在楼兰古城的下面发现了一幅巨大的壁画,壁画上被标记出了N个点,经测量发现这N个点的水平位置和竖直位置是两两不同的. 西部314认为这幅壁画所包含的信息与这N个点的相对位置有关,因此不妨设坐标分别为(1,y1),(2,y2),…,(n,yn)(1,y1),(2,y2),…,(n

Codeforces Round #609 (Div. 2)E--K Integers(贪心+二分+树状数组+逆序对)

K Integers 参考博客:https://blog.csdn.net/Q755100802/article/details/103664555 [题意] 给定一个1到n的排列,可以交换相邻的两个元素. 现在定义一个函数f(x),表示在原排列中,通过交换操作,形成一个1,2,3....x的排列的子串,需要的最小操作步骤. 子串意味着这个排列必须是相邻的.现在你需要求出f(1),f(2),f(3)......f(n). [分析] 在1~x这几个元素相邻的情况下,因为最后排列不存在逆序对,根据贪