【逆序对】序列

来源:互联网 发布:排雷软件 编辑:程序博客网 时间:2024/05/21 10:36


这个很简单,就是归并排序求逆序对。

但是要小心,a[l1] <= a[l2],而不是a[l1] < a[l2]。

虽然两个相等,交换也无所谓,但是统计等于并不是逆序,答案会改变。


#include <cstdio>#include <string>#include <cstring>long ans = 0;long a[50010];long b[50010];long getint(){long rs=0;bool sgn=1;char tmp;do tmp=getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp=='-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}void merge(long l,long mid,long r){long l1 = l;long l2 = mid+1;long s = l-1;while (l1<mid+1 || l2<r+1){if (l1<mid+1 && (l2>r || a[l1]<=a[l2]))b[++s] = a[l1++];else{b[++s] = a[l2++];ans += (mid-l1+1);}}for (long i=l;i<r+1;i++)a[i] = b[i];}long quick_power(long b,long c){long tmp = 2;long rs = 1;while (b){if (b&1){rs=(rs*tmp)%1991;}b >>= 1;tmp = (tmp*tmp)%1991;}return rs;}void merge_sort(long l,long r){if (l == r)return;long mid = (l+r)>>1;merge_sort(l,mid);merge_sort(mid+1,r);merge(l,mid,r);}int main(){freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);long n = getint();for (long i=1;i<n+1;i++){a[i] = getint();}merge_sort(1,n);long ans2 = quick_power(ans,1991);printf("%ld",ans2);return 0;}