luogu CF1102E Monotonic Renumeration |數學+動態規劃

题意翻译

给出一个长为(n)的序列(a_1...a_n)​,根据序列(a)构建一个单调的序列(b),要求:

(b_1 = 0)
对于任何一组i, j ((1 le i, j le n)) ,如果(a_i = a_j),则(b_i=b_j)( (ai≠aj) 时无限制)
对于(i in [1, n - 1]),(b_{i+1} = b_{i})​或(b_{i+1} = b_{i}+1)

例如,(a=[1,2,1,2,3])时,(b)可以是([0,0,0,0,0])([0,0,0,0,1])

请计算bbb的数量,答案对(99824435)取模

(1 le n le 2 cdot10^5), (1le a_i le10^9)



#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=998244353,N=2e5+10;
#define int long long
int n,a[N],b[N],L[N],R[N];
int vis[N],dp[N];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+len,a[i])-b;
	memset(L,0x7f,sizeof(L));
	memset(R,0xcf,sizeof(R));
	for(int i=1;i<=n;i++){
		L[a[i]]=min(L[a[i]],i);
		R[a[i]]=max(R[a[i]],i);
	}
	for(int i=1;i<=n;i++){
		if(L[i]>=R[i])continue;
		vis[L[i]+1]++,vis[R[i]+1]--;
	}
	for(int i=1;i<=n;i++)vis[i]+=vis[i-1];
	dp[1]=1;
	for(int i=2;i<=n;i++){
		if(vis[i])dp[i]=dp[i-1];
		else dp[i]=dp[i-1]*2%mod;
	}
	printf("%lld
",dp[n]);
}
原文地址:https://www.cnblogs.com/naruto-mzx/p/12689528.html