51Nod1019题(逆序数)

最开始不知道归并排序,于是这道题就各种花式T,最好的一次1015ms,也是醉了。

说下最开始的想法:   用<set>插入第一个数,随后输入的数依次比较<set>中的元素,如果与其中 <= 其中一个数,

则后面的数都可作为其逆序数,用  “<set>当前容量” 减去 “当前数的位置” 就是这个数所产生的逆序数对数,最后插入该数,

还是粘一下代码吧(TLE)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
#include <climits>
#include <cmath>
#define maxn 400000
using namespace std;

int main()
{
    //freopen("lxx.txt","r",stdin);
    int i,j,group;
    char ch;
    while(scanf("%d",&group)!=EOF)
    {
        set<int>s;
        set<int>::iterator it;
        int d[group],a[group];
        scanf("%d",&a[0]);
        s.insert(a[0]);
        int ans=0;
        for(i=1; i<group; ++i)
        {
            scanf("%d",&a[i]);
            int cnt=0;  //记录当前数在set中遍历时所在位置
            for(it=s.begin(); it!=s.end(); ++it)
            {
                if(a[i]<=*it)
                {
                    ans+=(s.size()-cnt);
                    break;
                }
                ++cnt;
            }
            s.insert(a[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

然后再说下AC想法,其实就是归并排序的简单应用(归并排序 时间复杂度nlogn 空间n 且稳定)

归并算法网上讲的很多也很全面,这就不说了。

这个题只是注意下每次判断到符合条件时,cnt(总逆序数)加的个数

#include<iostream>
#include<sstream>
#include<stack>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cctype>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>                          //AC 140ms  2452KB
#include<set>
#define inf 0x3f3f3f3f
#define N 50001

using namespace std;

int a[N],temp[N];
int cnt;
void mer(int x,int mid,int y)   //合并过程
{
    int i=x;
    int j=mid+1;
    int k=0;
    while(i<=mid&&j<=y)
    {
        if(a[i]<=a[j]) temp[k++]=a[i++];
        else {temp[k++]=a[j++]; cnt+=(mid+1-i);}
        //这里是mid+1-i,而不是j-i,主要是j-i会重复统计逆序数(mid+1到j在之前递归时已经统计过了)
    }
    while(i<=mid) temp[k++]=a[i++];
    while(j<=y) temp[k++]=a[j++];
    for(i=0; i<k; ++i) a[x+i]=temp[i];
}

void mergesort(int x,int y)
{
    if(x<y)
    {
        int mid=x+((y-x)>>1);
        mergesort(x,mid);
        mergesort(mid+1,y);
        mer(x,mid,y);
    }
}

int main()
{
    int n,i,j;
   // freopen("lxx.txt","r",stdin);
    while(scanf("%d",&n)!=EOF)
    {
        cnt=0;
        for(i=0; i<n; ++i)
        {
            scanf("%d",&a[i]);
        }
        mergesort(0,n-1);
        printf("%d\n",cnt);
    }
    return 0;
}
时间: 2024-08-06 03:29:46

51Nod1019题(逆序数)的相关文章

逆序数 技巧题

A permutation of size n is an array of size n such that each integer from 1 to n occurs exactly once in this array. An inversion in a permutation p is a pair of indices (i,?j) such that i?>?j and ai?<?aj. For example, a permutation [4,?1,?3,?2] cont

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

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是否在序列中出现过,如果数字

HDU 4911 Inversion 求逆序数对

点击打开链接 Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1106    Accepted Submission(s): 474 Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two adjacent num

E - 归并排序 求逆序数

Description One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are out of order with respect to each other. For instance, in the letter sequence ``DAABEC'', this measure is 5, since D is greater than four letters to

求逆序数(归并排序)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整

poj 1007 DNA Sorting (求逆序数)

DNA Sorting Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 83069   Accepted: 33428 Description One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are out of order with respect to each other. For instanc

逆序对问题---求逆序数

逆序数:在一个排列中,如果一对数的前后位置与大小顺序相反, 即前面的数大于后面的数,那么它们就称为一个逆序. 一个排列中逆序的总数就称为这个排列的逆序数.逆序数为偶数的排列称为偶排列:逆序数为奇数的排列称为奇排列. { 设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同. 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这一个有序对称为 A 的一个逆序对,也称作逆序.逆序对的数量称作逆