zoukankan      html  css  js  c++  java
  • 求逆序数

                      求逆序数

                        时间限制:2000 ms  |  内存限制:65535 KB
                                  难度:5
    描述

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

    现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。

    比如 1 3 2 的逆序数就是1。

    输入
    第一行输入一个整数T表示测试数据的组数(1<=T<=5)
    每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000)
    随后的一行共有N个整数Ai(0<=Ai<1000000000),表示数列中的所有元素。

    数据保证在多组测试数据中,多于10万个数的测试数据最多只有一组。
    输出
    输出该数列的逆序数
    样例输入
    2
    2
    1 1
    3
    1 3 2
    样例输出
    0
    1
    用到合并排序算法
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    #define MAX 1000010
    #define MN 1000000050
    __int64 sum; int a[MAX];
    int L[MAX/2],R[MAX/2];
    void merge(int A[],int p,int q,int r)
    {
     int n1=q-p+1,n2=r-q,i,j; 
     for (i=1;i<=n1;i++)
      L[i]=A[p+i-1];
     for (i=1;i<=n2;i++)
      R[i]=A[q+i];
     R[n2+1]=L[n1+1]=MN;
     i=j=1;
     for (int k=p;k<=r;k++)
     {
      if(L[i]<=R[j])
       A[k]=L[i++];
      else
      {
       A[k]=R[j++];
       sum+=n1-i+1;
      }
     }
    }
    void merge_sort(int A[],int p,int r)
    {
     int q;
     if(p<r)
     {
      q=(p+r)>>1;
      merge_sort(A,p,q);
      merge_sort(A,q+1,r);
      merge(A,p,q,r);
     }
    }
    int main()
    {
     int t,i,n,num,k;
     scanf("%d",&t); 
     while(t--)
     {  
      scanf("%d",&n);sum=0;
      for(i=1;i<=n;i++)
      {
       scanf("%d",&a[i]);   
      }
      merge_sort(a,1,n);
      printf("%I64d\n",sum);
     }
     return 0;
    }
  • 相关阅读:
    BOM与DOM的区别与联系
    HTTP与HTTPS的区别
    总结一下C++与C#之间的区别
    点标记(lambda表达式+linq查询标记符)与linq语句(查询表达式)
    java多线程:继承Thread和实现Runable接口的区别
    打印BroadcastReceiver的所有接受者
    修改apk里面的源码
    关于启动模式中的问题
    onSaveInstanceState和onRestoreInstanceState()
    Options Menu的android3.0以上和以下版本显示刷新原理,刷新适配
  • 原文地址:https://www.cnblogs.com/qijinbiao/p/2213009.html
Copyright © 2011-2022 走看看