链接
题意:
给出你一段序列,让你找出yig9ong多少先增后减和多少先减后增的三元组。 ( i , j , k ) ( i < j < k ) (i,j,k)(i<j<k) (i,j,k)(i<j<k)
分析:
用树状数组维护逆序对。先正序维护一个逆序对,再倒序维护逆序对,两两相乘再求和即可。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn= 2e5+7;
ll n;
ll a[maxn];
ll tree[maxn];
ll lowbit(ll x){
return x&(-x);
}
void update(ll x,ll d){
while(x<=n){
tree[x]+=d;
x+=lowbit(x);
}
}
ll query(ll x){
ll ans=0;
while(x>0){
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
ll l[maxn],r[maxn];
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
l[i]=query(a[i]-1);
r[i]=query(n)-query(a[i]);
update(a[i],1);
}
ll ans1=0;
ll ans2=0;
memset(tree,0,sizeof tree);
for(int i=n;i>=1;i--){
ans1+=l[i]*query(a[i]-1);
ans2+=r[i]*(query(n)-query(a[i]));
update(a[i],1);
}
cout<<ans2<<" "<<ans1<<endl;
return 0;
}