题目链接:http://codeforces.com/problemset/problem/459/D
将序列离散化之后,很方便就可以处理出f值
逆序将后缀F值加入树状数组中,同时更新ans值
代码:
#include <bits/stdc++.h>
#define sf scanf
#define pf printf
using namespace std;
typedef long long LL;
const int maxn = 1000000 + 50;
LL totSize;
int n;
LL A[maxn],tmpa[maxn],preF[maxn],sufF[maxn];
map<LL,LL> HASH;
LL SUM[maxn];
void ADD(LL x,LL v){
while(x <= totSize){
SUM[x] += v;x = x + (x & (-x));
}
}
LL GETSUM(LL x){
LL ret = 0;
while(x > 0){
ret += SUM[x];x = x - (x & (-x));
}return ret;
}
int main(){
// freopen("rand.txt","r",stdin);
// freopen("out1.txt","w",stdout);
HASH.clear();
sf("%d",&n);
for(int i = 1;i <= n;++i) sf("%lld",&A[i]);
memcpy(tmpa,A,sizeof tmpa);
sort(tmpa + 1,tmpa + 1 + n);totSize = unique(tmpa + 1,tmpa + 1 + n) - tmpa - 1;
for(int i = 1;i <= totSize;++i) HASH[tmpa[i]] = i;
for(int i = 1;i <= n;++i) A[i] = HASH[A[i]];
memset(tmpa,0,sizeof tmpa);
for(int i = 1;i <= n;++i){
tmpa[A[i]]++;
totSize = max(totSize , preF[i] = tmpa[A[i]]);
}
memset(tmpa,0,sizeof tmpa);
for(int i = n;i;--i){
tmpa[A[i]]++;
totSize = max(totSize , sufF[i] = tmpa[A[i]]);
}
long long ans = 0;
memset(SUM,0,sizeof SUM);
for(int i = n;i > 1;--i){
ADD(sufF[i],1);
ans = ans + GETSUM(preF[i - 1] - 1);
}
pf("%lld\n",ans);
return 0;
}