M元上升子序列【樹狀數組+dp】

多元組-牛客網

題解
在這裏插入圖片描述

ac代碼

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
const int mod =1e9+7;
ll n,m,a[maxn],b[maxn];//用來離散化
ll f[51][maxn];//動態規劃的數組 f[i][j]表示終點爲a[j]的i元組上升序列的個數 
ll t[maxn];//樹狀數組 

//快讀
ll read(){
	ll k=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		k=10*k+c-'0';
		c=getchar();
	}
	return f*k;
}

//下面是樹狀數組的基本操作
ll lowbit(ll x ){
	return x&-x;
}
//樹狀數組更新
void update(ll i,ll k){
	while(i<=n){
		t[i]=(t[i]+k)%mod;
		i+=lowbit(i);
	}
}
//樹狀數組前綴和
ll query(ll i){
	ll res=0;
	while(i>0){
		res=(res+t[i])%mod;
		i-=lowbit(i); 
	}
	return res;
}


int main(){	
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		a[i]=read(),b[i]=a[i];
	}
	sort(b+1,b+n+1);	
	unique(b+1,b+n+1);
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+n+1,a[i])-b;//離散
		
	for(ll j=1;j<=n;j++) f[1][j]=1;//初始化
	
	for(ll i=2;i<=m;i++){//上升序列的長度 
		memset(t,0,sizeof(t));//樹狀數組清零 
		for(int j=1;j<=n;j++){
			f[i][j]=query(a[j]-1);//
			update(a[j],f[i-1][j]);
		}
	} 
	ll ans=0;
	for(int i=1;i<=n;i++) ans+=f[m][i];
	printf("%d",ans%mod);
		
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章