洛谷1637 三元上升子序列

题目描述

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 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;
}
阅读更多
换一批

没有更多推荐了,返回首页