逆序数

51Nod

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input

第1行:N,N为序列的长度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output

输出逆序数

Input示例

4
2
4
3
1

Output示例

4
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#define N 52005
using namespace std;
int a[N],c[N],d[N];

int Lowbit(int t)
{   ///设k为t末尾0的个数,则求得为2^k=t&(t^(t-1));
    return t&(t^(t-1));
}
void update(int x)
{
    while(x > 0)
    {
        c[x]+=1;
        x -= Lowbit(x);
    }
}
int sum(int li)
{
    int sum=0;
    while(li<=N)
    {
        sum+=c[li];
        li=li+Lowbit(li);
    }
    return sum;
}

map<int ,int>q;
int main()
{
    int n,x;
    int Sum;
    while(scanf("%d",&n)!=EOF)
    {
        Sum=0;
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            d[i]=a[i];
        }

        sort(a,a+n);
        int pre=1,tot=1;
        for(int i=0;i<n;i++)
        {
            if(a[i]==pre)
            {
                a[i]=tot;
                q[pre]=tot;
            }
            else
            {
                pre=a[i];
                a[i]=++tot;
                q[pre]=tot;
            }
        }

        for(int i=0;i<n;i++)
        {
            d[i]=q[d[i]];
        }
//        for(int i=0;i<n;i++)
//            cout<<d[i]<<" ";
        for(int i=0;i<n;i++)
        {
            Sum+=sum(d[i]+1);
            update(d[i]);
        }
        printf("%d\n",Sum);
    }
    return 0;
}
时间: 2024-12-17 17:09:02

逆序数的相关文章

ACM ICPC 2011–2012, NEERC, Northern Subregional Contest J. John’s Inversions(合并排序求逆序数对数)

题目链接:http://codeforces.com/gym/100609/attachments 题目大意:有n张牌,每张牌有红色和蓝色两面,两面分别写了一些数字,同种颜色的任意两个数字若排在前面的数字比排在后面的数字大就叫做一对逆序数.求怎样排序得到的逆序数对最少. 解题思路:其中一种颜色的数字是顺序且这种颜色数字相同时对应的另一种颜色的数字是顺序时得到的逆序数对数最少.难点在于求逆序数对数.因为数量很大O(n^2)复杂度不能满足,这里根据合并排序的原理求解每个数字前面有多少个比它大的数字,

CSU 1555 Inversion Sequence 给出逆序数求排列 splay

题目链接:点击打开链接 题意: 给出逆序数的值,求原序列(一个1-N的排列) 1, 2, 0, 1, 0 表示1的逆序数是1,2的逆序数是2,3的逆序数是0··· 思路: 从最后一个数开始插,每次插到当前序列的第a[i]个数.. splay模拟 == 这个方法比较直(wu)观(nao),别的方法并没有想出来.. #include <cstdio> #include <iostream> #include <cstring> #include <queue>

1019 逆序数

1019 逆序数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4.给出一个整数序列,求该序列的逆序数. Input 第1行:N,N为序列的长度(n <= 50000) 第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9) Ou

归并排序_逆序数

归并排序求逆序数 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.一个排列中所有逆序总数叫做这个排列的逆序数.也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序.一个排列中所有逆序总数叫做这个排列的逆序数. 1 #include<cstdio> 2 #in

ZOJ-2386 Ultra-QuickSort 【树状数组求逆序数+离散化】

Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input seque

UVa 1620 懒惰的苏珊(逆序数)

https://vjudge.net/problem/UVA-1620 题意:给出一个序列,每次可以翻转4个连续的数,判断是否可以变成1,2,3...n. 思路:考虑逆序数,通过计算可以得出每次翻转4个连续的数,如果这4个数原来的逆序数为x,那么翻转之后逆序数会变为6-x. 1.n为偶数时,总会有序列的逆序数为偶数 2.当n为奇数时,并且这个所给的序列的逆序数为奇数,不管怎么变换 他的逆序数不能变为 偶数. 这两个结论是别人博客看来的,不过我不太清楚怎么推导来着.有人懂得话希望能告诉我一下. 1

ZYB&#39;s Premutation(有逆序数输出原序列,线段树)

ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 758    Accepted Submission(s): 359 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each pr

POJ3067 Japan【树状数组】【逆序数】

题目链接: http://poj.org/problem?id=3067 题目大意: 有两排的城市,一排N个城市,编号为1~N,一排M个城市,编号为1~M.这两排城市之间有K条路. 路都是直线连接,问:这些路,有多少道路是相交的,并且焦点不是城市所在的点,求出交点个数. 思路: 树状数组的思想.参考网上的图,先将所有边(u,v)按u升序排列,如果u相同,则按v升序排列.可 以看出来,路(u1,v1)和路(u2,v2)如果有交点的话,u1 > u2 并且 v1 < v2,或者 u1 < u

HDU2689 Sort it【树状数组】【逆序数】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2689 题目大意: 求把一个具有N个不同元素的序列通过交换两个相邻的元素转换成升序序列需要进行的交换次数 是多少. 例如:1 2 3 5 4,只需要交换5和4,交换次数为1次. 思路: 典型的求逆序数题.其实可以直接暴力过.但是用树状数组效率比较高.对于值为a第i个元素, 需要交换次数为前i个元素中大于a的元素个数,即逆序数. 用树状数组来做,数组Tree[i]表示数字i是否在序列中出现过,如果数字