P1637
三元上升子序列
题目描述
Erwin 最近对一种叫 thair
的东西巨感兴趣。。。
在含有 \(n\) 个整数的序列 \(a_1,a_2,\ldots,a_n\) 中,三个数被称作thair
当且仅当 \(i<j<k\) 且 \(a_i<a_j<a_k\)。
求一个序列中 thair
的个数。
输入格式
开始一行一个正整数 \(n\),
以后一行 \(n\) 个整数 \(a_1,a_2,\ldots,a_n\)。
输出格式
一行一个整数表示 thair
的个数。
样例 #1
样例输入 #1
4
2 1 3 4
样例输出 #1
2
样例 #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\le100\);
- 对于 \(60\%\) 的数据 保证 \(n\le2000\);
- 对于 \(100\%\) 的数据 保证 \(1 \leq n\le3\times10^4\),\(1\le a_i\leq 10^5\)。
离散化后 两次树状数组统计即可
注意 一定是 f1[i]=ask(a[i]-1) 不能 ask(a[i])-1
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e4+5;
int n,tr[N<<1],f1[N],f2[N],a[N],b[N],c[N];
inline int lowbit(int x) {
return x&(-x);
}
inline void add(int p,int k) {
for(; p<=n; p+=lowbit(p))
tr[p]+=k;
}
int ask(int p) {
int sum=0;
for(; p; p-=lowbit(p))
sum+=tr[p];
return sum;
}
signed main() {
ios::sync_with_stdio(false);
cin>>n;
int tot=0;
int maxx=-1;
for(int i=1; i<=n; i++)cin>>b[i],c[i]=b[i];
sort(b+1,b+n+1);
for(int i=1; i<=n; i++) {
int pos=lower_bound(b+1,b+n+1,c[i])-b;
a[i]=pos;
}
for(int i=1; i<=n; i++) {
int x=a[i];
add(x,1);
f1[i]=ask(x-1);
}
memset(tr,0,sizeof(tr));
for(int i=n; i>=1; i--) {
int x=a[i];
add(x,1);
f2[i]=n-i+1-ask(x);
}
for(int i=1; i<=n; i++)tot+=f1[i]*f2[i];
cout<<tot<<"\n";
return 0;
}