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;
}
posted @ 2023-04-28 22:21  N0zoM1z0  阅读(14)  评论(0编辑  收藏  举报