【归并排序】序列(sequence.pas/c/cpp)

序列
sequence.pas/c/cpp

生活中,大多数事物都是有序的,因为顺序的美是最令人陶醉的。所以现在RCDH看了不顺的东西就头痛。所以他想让世界变成有序,可是他只是一个无名小辈,所以只好对数字序列下手。据他所知序列的混乱程度是由“逆序对”的个数决定,公式是Q=2^n,其中Q是指混乱程度,n是指这个序列“逆序对”的个数。逆序对是这样定义的:假设序列中第I个数是ai,若存在I<J,使得ai>aj,则<ai,aj>就为一个逆序对。你的任务是给定一个序列,计算其混乱程度Q。这个数可能会比较大,你只需输出Q mod 1991的结果。

输入
  第一行,整数n,表示序列中有n个数。
  第二行,有n个数
输出
  仅一行,Q mod 1991的值

【样例输入】sequence.in
4
1 3 4 2
【样例输出】sequence.out
4

注释:样例中共有2个逆序对,故Q=2^2=4,所以Q mod 1991=4

【数据规模】
  对于30%的数据
    2<=n<=1000
  对于100%的数据
    2<=n<=50000
  数列中的每个数不超过10000000的正整数

 

这一题利用归并排序,合并的时候在两个序列中,如果取右区间的数,就表示左区间的数都大于他,那么左区间有多少就有多少逆序对

C++ Code

/*
C++ Code
http://oijzh.cnblogs.com
*/
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 50010

int n,a[MAXN],temp[MAXN],sum=0;

void merge(int ll,int mid,int rr)
{
    int l=ll,r=mid+1;
    for(int i=ll;i<=rr;i++)
    {
        if((l<=mid)&&(r>rr||a[l]<=a[r]))
        {
            temp[i]=a[l];
            l++;
        }
        else{
            temp[i]=a[r];
            r++;
            sum+=mid-l+1;
        }
    }
    for(int i=ll;i<=rr;i++)a[i]=temp[i];
}

void msort(int ll,int rr)
{
    if(ll>=rr)return;
    int mid=(ll+rr)>>1;
    msort(ll,mid);
    msort(mid+1,rr);
    merge(ll,mid,rr);
}

int pw(int a,int b,int mod)
{
    int sum=1,t=a;
    while(b)
    {
        if((b&1)==1) sum=(sum*t)%mod;
        t*=t;t%=mod;
        b=b>>1;
    }
    return sum;
}

int main()
{
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    msort(1,n);
    sum=pw(2,sum,1991);
    printf("%d",sum);
    return 0;
}

 

 

posted @ 2012-10-19 17:50  jiangzh  阅读(579)  评论(0编辑  收藏  举报