这个很简单,就是归并排序求逆序对。
但是要小心,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;
}