思路如下:
他让求三元上升子序列,我就先求二元,一个数可以作为顺序列里的小数(be数组),也可以是大数(en数组),那么当这个数是一个数列的大数,另一个数列的小数时,就能组成三元上升子子序列
举个例子:1 2是顺序列,2 3也是, 那么1 2 3就是三元上升子序列,结果就是2的be[2]*en[2]
(本人太弱了,不知道思路对不对,请各位大佬指点)
//
// main.cpp
// 三元上升子序列
//
// Created by hjc on 2024/10/6.
//
#include <iostream>
#include <queue>
#include <map>
using namespace std;
const int N=3*1e5+100;
map<long long,long long>mp;
long long a[N],b[N],be[N],en[N];
//a为原数组排序后结果,b为离散化结果,be代表这个数作为开头个数,en代表这个数作为结尾的个数
void msort(long long l,long long r){
//二分
if(l>=r)return ;
int mid=(l+r)>>1;
msort(l,mid);
msort(mid+1,r);
int nl=l,nr=mid+1,num1=0,cnt=0;
while(nl<=mid&&nr<=r){
if(b[nl]>b[nr]){
a[nl-l+nr-mid]=b[nl];
be[b[nl]]+=cnt;
nl++;
}
else{
a[nl-l+nr-mid]=b[nr];
en[b[nr]]+=mid-nl+1;
cnt++;
nr++;
}
}
while(nl<=mid){
a[nl-l+nr-mid]=b[nl];
be[b[nl]]+=cnt;
nl++;
}
while(nr<=r){
a[nl-l+nr-mid]=b[nl];
nr++;
}
for(int i=l;i<=r;i++){
b[i]=a[i-l+1];
}
}
int main(int argc, const char * argv[]){
int n;
cin>>n;
a[0]=1e9;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
//离散化
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
long long bi=b[i];
b[i]=upper_bound(a+1,a+1+n,b[i])-a-mp[b[i]]-1;
mp[bi]++;
}
msort(1,n);
long long ans=0;
for(int i=1;i<=n;i++){
// cout<<be[i]<<" "<<en[i]<<"\n";
ans+=en[i]*be[i];
}
cout<<ans<<endl;
}