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]);
}
不以物喜,不以己悲