【归并排序】序列(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; }
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh