三元上升子序列
阿新 • • 發佈:2018-12-18
題目
思路
首先,對於任意一個選定的數aj而言
要求的是1~j-1中比aj小的數的個數
乘以j+1~n中比aj大的數的個數
求出數的個數可以直接使用樹狀陣列
最後直接統計結果就行了
但是,考慮到N的範圍很小
但是ai<maxlongint
因此,如果不使用離散化的話,可能會炸空間
程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=3e4+10; int n,m; int c1[maxn],c2[maxn]; int A[maxn],_A[maxn]; int Lef[maxn],Rit[maxn]; inline int _Q(int val){ return lower_bound(_A+1,_A+m+1,val)-_A; } inline int lowbit(int i){ return i&(-i); } void add(int *C,int pos,int val){ while(pos<=maxn){ C[pos]+=val; pos+=lowbit(pos); } } int sum(int *C,int pos){ int res=0; while(pos>0){ res+=C[pos]; pos-=lowbit(pos); } return res; } int main(){ cin>>n; for(int i=1;i<=n;++i){ scanf("%d",&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){ add(c1,_Q(A[i]),1); Lef[i]=sum(c1,_Q(A[i])-1); } for(int i=n;i>=1;--i){ add(c2,_Q(A[i]),1); Rit[i]=n-i-(sum(c2,_Q(A[i]))-1); } long long ans=0; for(int i=2;i<n;++i) ans+=Lef[i]*Rit[i]; cout<<ans; return 0; }