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

来源:互联网 发布:泰克网络实验室靠谱吗 编辑:程序博客网 时间:2024/05/20 23:56

序列
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++ Codehttp://blog.csdn.net/jiangzh7*/#include<cstdio>#include<cmath>using namespace std;#define MAXN 50010int 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;}

 

 

原创粉丝点击