https://www.nowcoder.com/acm/contest/38/E
假如i j是逆序对
那么他们的贡献就是i*(n-j+1)
假如i和j是逆序对 k和j是逆序对 那么就是(k+j)*(n-i+1) i>k,j
那么在更新树状数组的时候add a[i]的位置,那么就达到了k+j的效果
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef unsigned __int128 ll;
typedef ll LL;
int n, m;
int a[N], b[N];
ll bit[N];
inline void add(int i, ll x)
{
for ( ; i <= m; i += i & -i) bit[i] += x;
}
inline ll query(int i)
{
ll r = 0;
for ( ; i; i -= i & -i) r += bit[i];
return r;
}
inline ll query(int l, int r) { return query(r) - query(l - 1); }
void print(ll n)
{
if (n < 10) return (void)putchar(n + '0');
print(n / 10);
putchar(n % 10 + '0');
}
void out(ll n)
{
print(n);
puts("");
}
int main()
{
//freopen( "1.txt" , "r" , stdin );
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf("%d", a+i);
b[i] = a[i];
}
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; ++i)
a[i] = lower_bound(b + 1, b + m + 1, a[i]) - b;
ll ans = 0;
for (int i = 1; i <= n; ++i)
{
add(a[i], i);
ans += (ll)(n - i + 1) * query(a[i] + 1, m);
}
out(ans);
return 0;
}