洛谷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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章