给出定义 i < j < k i< j< k i<j<k且 a i < a j < a k a_{i}<a_{j}<a_{k} ai<aj<ak的子序列为三元组,求问序列中有多少个三元组。直接树状数组维护以每个点为中心的前后各有多少,一遍统计答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=3e4+7;
int a[N],b[N],tot;
int t[N];
int l[N],r[N];
int lowbit(int x) {
return x&(-x);
}
void add(int x,int k) {
for(int i=x;i<=tot;i+=lowbit(i))
t[i]+=k;
}
int query(int x) {
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
sum+=t[i];
return sum;
}
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
tot=unique(b+1,b+1+n)-(b+1);
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
for(int i=1;i<=n;i++) {
l[i]=query(a[i]-1);
add(a[i],1);
}
memset(t,0,sizeof(t));
for(int i=n;i>=1;i--) {
r[i]=query(tot)-query(a[i]);
add(a[i],1);
}
ll ans=0;
for(int i=1;i<=n;i++)
ans+=l[i]*r[i];
printf("%lld\n",ans);
return 0;
}