狗b题,气死我了,思路正确,离散化的时候相同元素要按照位置从小到大排,然后不用两遍求,手推一下,做减法就可以了~
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
#define ll long long
const int N = 50010;
vector<int>vec;
struct Node
{
int val;
int pos;
};
Node node[N];
int c[N], reflect[N],n;
long long a[N] ,b[N] , d[N],e[N],suma[N], sumb[N];
bool cmp(const Node& a, const Node& b)
{
if(a.val == b.val) return a.pos < b.pos;
return a.val < b.val;
}
int lowbit(int x)
{
return x & (-x);
}
void update(int x)
{
while (x <= n)
{
c[x] += 1;
x += lowbit(x);
}
}
int getsum(int x)
{
int sum = 0;
while (x > 0)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int ni[N],ini[N],in[N];
ll aa[N], bb[N];
map<int,int>mp,mpp;
int main()
{
// freopen("111.txt","r",stdin);
while (scanf("%d", &n) != EOF)
{
mp.clear(); mpp.clear();
for (int i = 1; i <= n; ++i)
{
scanf("%d", &node[i].val);ini[i] = node[i].val;in[i] = node[i].val;
// num[node[i].val] ++;in
node[i].pos = i;mpp[ini[i]] ++;
}
for(int i = 1 ; i <= n ; i++){
ni[i] = node[n - i + 1].val;
}
sort(node + 1, node + n + 1, cmp); //排序
sort(ini + 1, ini + 1 + n);
for (int i = 1; i <= n; ++i) {reflect[node[i].pos] = i;
int l = lower_bound(ini + 1 , ini + 1 + n, ini[i]) - ini;
int r = upper_bound(ini + 1 , ini + 1 + n, ini[i]) - ini;
suma[node[i].pos] = l - 1 ; sumb[node[i].pos] = n - r + 1;
}
for (int i = 1; i <= n; ++i) c[i] = 0; //初始化树状数组
ll ans = 0;
for (int i = 1; i <= n; ++i)
{
update(reflect[i]);
int tmp = getsum(reflect[i]);
d[i] = tmp - 1 - mp[in[i]];
e[i] = i - tmp;
a[i] = suma[i] - d[i] ;
b[i] = sumb[i] - e[i] ;
ans += i - tmp;
mp[in[i]]++;
}
ll anss = 0 ;
anss = 1ll * n * (n - 1) / 2 ;
mp.clear();//vec.clear();
for(int i = 1; i <= n ; i++){
mp[ini[i]] ++;
}
map<int,int>::iterator it;
// cout <<" anss= " << anss <<endl;
for(it = mp.begin() ; it != mp.end(); it ++){
//cout << *it <<endl;
int now = (*it).second;
anss -= 1ll * (now * (now - 1)) / 2;
}
ans *= (anss - ans);
for(int i = 1; i <= n ; i++){
ans -= (b[i] + d[i]) * (a[i] + e[i]);
}
printf("%I64d\n", ans);
}
return 0;
}
/*
4
99 18 101 23
9
1 1 2 2 2 2 1 1 1
6
1 1 2 2 2 2
20
1 1 2 2 2 2 1 1 1 1 1 2 1 1 1 1 1 2 2 2
*/