题目描述
珂朵莉给了你一个序列,有(n*(n+1))/2
个子区间,求出她们各自的逆序对个数,然后加起来输出。
对于每个区间,其贡献为(n-i+1)*SUM
.
SUM = 前面插入arr[k]值大于当前值的下标k的和
因为对一个区间来说其贡献为(n-i+1)*l,一个是右界,一个是左界,而左界的和即为上面的SUM。
//
// Created by SANZONG on 2021/7/7.
//
#include "bits/stdc++.h"
using namespace std;
const int maxn = 1e6+10;
int arr[maxn];
int cp[maxn];
int n;
long long t[maxn];
int lowerbit(int x)
{
return x&(-x);
}
void update(int p,int i)
{
while (p <= n)
{
t[p]+=i;
p += lowerbit(p);
}
}
__int128 getsum(int p)
{
__int128 res = 0;
while (p > 0)
{
res += t[p];
p -= lowerbit(p);
}
return res;
}
void print(__int128 x)
{
if(!x)
{
puts("0");
return ;
}
string ret="";
while(x)
{
ret+=x%10+'0';
x/=10;
}
reverse(ret.begin(),ret.end());
cout<<ret<<endl;
}
signed main()
{
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
cp[i] = arr[i];
}
sort(cp+1,cp+1+n);
for (int i = 1; i <= n; ++i) {
arr[i] = lower_bound(cp+1,cp+1+n,arr[i])-cp;
}
__int128 ans = 0;
for (int i = 1; i <= n; ++i) {
ans += (n-i+1)*(getsum(n) - getsum(arr[i]));
update(arr[i],i);
}
print(ans);
}