多元组
这道题是 洛谷·P1637 三元上升子序列 的变式,也可以说是加强版;
树状数组可以表示为dp[i][j],表示第 i 元组,1–j 的个数( j 是离散化后的);
这个二维就加在第几元组上面,可以想到第 i 元组,可以由第 i-1 元组转化而来;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,LL>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100100;
const int M=400100;
const int mod=1e9+7;
int n,m,cnt,a[N],b[N];
LL tr[60][N];
int lowbit(int k){return k&-k;}
void add(int k,int p,LL q){
while(p<=cnt){
(tr[k][p]+=q)%=mod;
p+=lowbit(p);
}
}
LL sum(int k,int p){
LL s=0;
while(p!=0){
(s+=tr[k][p])%=mod;
p-=lowbit(p);
}
return s;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
cnt=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
for(int i=1;i<=n;i++){
add(1,a[i],1ll);
for(int j=2;j<=m;j++){
LL s=sum(j-1,a[i]-1);
add(j,a[i],s);
}
}
printf("%lld",sum(m,cnt));
return 0;
}