题解:SP9650 TRIPINV - Mega Inversions
建议先做 P1908 逆序对。
可以想出,一个点所产生的逆序对数量就是右边比它小的,左边比它大的,相乘后,便是这个点所产生的逆序对数量。右边比它小的与左边比它大的数的个数可以用树状数组维护。
供上代码:(离散化方便过双倍经验)
# include <bits/stdc++.h>
# define lowbit(x) (x & (-x))
using namespace std;
int n , tot , a[1000010] , b[1000010] , l[1000010] , r[1000010];
long long sum , tr[1000010];
inline void add(int x , int w)
{
while(x <= tot)
{
tr[x] += w;
x += lowbit(x);
}
return ;
}
inline int query(int x)
{
int sum = 0;
while(x)
{
sum += tr[x];
x -= lowbit(x);
}
return sum;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
for(int i = 1 ; i <= n ; i ++)
{
cin >> a[i];
b[i] = a[i];
}
sort(b + 1 , b + n + 1);
tot = unique(b + 1 , b + n + 1) - b - 1;
for(int i = 1 ; i <= n ; i ++)
{
a[i] = lower_bound(b + 1 , b + tot + 1 , a[i]) - b;
r[i] = query(tot) - query(a[i]);
add(a[i] , 1);
}
memset(tr , 0 , sizeof tr);
for(int i = n ; i >= 1 ; i --)
{
l[i] = query(a[i] - 1);
add(a[i] , 1);
}
for(int i = 1 ; i <= n ; i ++) sum += 1LL * l[i] * r[i];
cout << sum;
return 0;
}

浙公网安备 33010602011771号