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\), \(1\le 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\n",dp[n]);
}
posted @ 2020-04-13 09:51  白木偶君  阅读(110)  评论(0编辑  收藏  举报