題目描述
Erwin最近對一種叫"thair"的東西巨感興趣。。。
在含有n個整數的序列a1,a2......an中,
三個數被稱作"thair"當且僅當i<j<k且ai<aj<ak
求一個序列中"thair"的個數。
輸入輸出格式
輸入格式:開始一個正整數n,
以後n個數a1~an。
輸出格式:"thair"的個數
輸入輸出樣例
說明
對樣例2的說明:
7個"thair"分別是
1 2 31 2 41 2 31 2 41 3 42 3 42 3 4約定30%的數據n<=100
60%的數據n<=2000
100%的數據n<=30000
大數據隨機生成
0<=a[i]<=maxlongint
練習樹狀數組的好題
#include<bits/stdc++.h>
#define N 30010
using namespace std;
namespace program{
int n,a[N],A[N],l[N],r[N],c1[N],c2[N],m;
//我們可以用樹狀數組c[val]記錄已經被考慮的數中小於val的個數,初始化爲0,每次更新時,調用add(A[i],1)。
inline int lowbit(int x){
return x&(-x);
}
inline void add(int *c,int k,int val){
while(k<=N){
c[k]+=val;
k+=lowbit(k);
}return;
}
inline int Sum(int *c,int k){
int res=0;
while(k>0){
res+=c[k];
k-=lowbit(k);
}return res;
}
inline int Find(int x){
return lower_bound(A+1,A+m+1,x)-A;
}
inline void work(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],A[i]=a[i];
sort(A+1,A+n+1);
m=unique(A+1,A+n+1)-(A+1);//離散化
for(int i=1;i<=n;i++){
int oo=Find(a[i]);
add(c1,oo,1);//插入當前數字
l[i]=Sum(c1,oo-1);//比第i個數小且在其左邊的數的個數爲l[i]
}
for(int i=n;i>=1;i--){
int oo=Find(a[i]);
add(c2,oo,1);
r[i]=n-i-(Sum(c2,oo)-1);
}
long long res=0;
for(int i=2;i<n;i++)//枚舉中間那個數
res+=(l[i]*r[i]);//乘法原理
cout<<res<<'\n';
return;
}
}
int main(){
program::work();
return 0;
}