题目描述
Erwin最近对一种叫"thair"的东西巨感兴趣。。。
在含有n个整数的序列a1,a2…an中,
三个数被称作"thair"当且仅当i<j<k且ai<aj<ak
求一个序列中"thair"的个数。
输入格式
开始一个正整数n,
以后n个数a1~an。
输出格式
"thair"的个数
输入输出样例
输入 #1 复制
4
2 1 3 4
输出 #1 复制
2
输入 #2 复制
5
1 2 2 3 4
输出 #2 复制
7
说明/提示
对样例2的说明:
7个"thair"分别是
1 2 3 1 2 4 1 2 3 1 2 4 1 3 4 2 3 4 2 3 4 约定 30%的数据n<=100
60%的数据n<=2000
100%的数据n<=30000
大数据随机生成
0<=a[i]<=max long int
有点像个二维偏序。我们可以枚举每个中间数字,计算出前面比他小的数字的个数,与后面比他多的数字的个数,这个数字的贡献值就是两个值相乘。
计算数字的个数可以线段树(权值线段树)或者树状数组。 然后这道题需要离散化。就好了。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x&(-x))
using namespace std;
const int N=3e4+10;
int n,a[N],t[N],b[N],res,m,t1[N],t2[N];
inline int getid(int x){
return lower_bound(b+1,b+1+m,x)-b;
}
inline void add(int x,int v){
for(int i=x;i<=m;i+=lowbit(i)) t[i]+=v;
}
inline int ask(int x){
int res=0; for(int i=x;i;i-=lowbit(i)) res+=t[i]; return res;
}
signed main(){
cin>>n; for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
sort(b+1,b+1+n); m=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++){
add(getid(a[i]),1); t1[i]=ask(getid(a[i])-1);
}
memset(t,0,sizeof t);
for(int i=n;i>=1;i--){
add(getid(a[i]),1); t2[i]=ask(m)-ask(getid(a[i]));
}
for(int i=2;i<n;i++) res+=t1[i]*t2[i];
cout<<res<<endl;
return 0;
}