逆序數《求所有子序列的逆序對個數的和
阿新 • • 發佈:2019-01-29
題目
題解
一對逆序對對答案的貢獻是2^(n-2)
故統計出逆序對個數後乘上即可
注意序列長1的情況什麼什麼的
O( nlogn )
程式碼
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long int
#define mod 1000000007
LL a[1000005],b[1000005];
LL n;
LL ans;//極限情況500000*500000會爆,所以開LL
void mersort(LL x,LL y)
{
if (y-x<=1)
return ;
LL mid=(x+y)/2;
mersort(x,mid);
mersort(mid,y);
LL p=x,i=x,q=mid;
while(p<mid||q<y)
{
if(q==y||(p<mid&&a[p]<=a[q]))//注意,不是a[p]<=a[mid],弄清比較的物件
//x到y排序,所以應該和a[q]比,從而把後面的一到前面去。
b[i++]=a[p++];
else if(p==mid||a[p]>a[q])
{
if(p<mid) ans+=(mid-p);
b[i++]=a[q++];
}
}
for(LL i=x; i<y; i++)
a[i]=b[i];
}
LL qu(LL a,LL b)
{
LL anss=1;
while(b)
{
if(b&1)
{
anss=(anss*a)%mod;
}
b/=2 ;
a=(a*a)%mod;
}
return anss;
}
int main()
{
while(~scanf("%lld",&n))
{
//if(n==1) continue;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(LL i=0; i<n; i++)
scanf("%lld",&a[i]);
ans=0;
mersort(0,n);
LL anss=qu(2,n-2);
ans%=mod;
printf("%lld\n",(ans*anss)%mod);
}
return 0;
}