P8445 射命丸文的取材之旅
Question 问题 P8445 射命丸文的取材之旅
给定序列 \(\{a_n\},\{b_n\}\),求一个序列 \(\{c_n\}\) 满足 \(\forall i\in[1,n],c_i\in\{a_i,b_i\}\),最大化
\[\max\{r-l+1-\operatorname{mex}\{c_l,c_{l+1},\dots, c_{r-1},c_r\}\}(1\le l\le r\le n)
\]
并输出该式子可能的最大值。
Analysis 分析
这道题的提示有两个地方:
- 数据范围,40% 的数据中 \(a_i = b_i\) 直接把问题转换为给一个序列 \(\{c_n\}\) 求那个式子的最大值。
- 另一个是
mex
我们发现这玩意比较难处理,但是数据范围较小。
Solution
所以我们考虑枚举 mex
的值。设当前枚举的 mex
为 \(t\)。
考虑在 40% 的数据下,什么时候一个区间的 mex
不可为 \(t\) ,即区间内出现了 \(t\) 这个数。所以我们在当前枚举的情况下,将每一个 \(c_i = t\) 是为一个墙,(特别地,\(c_{n+1}=t\) )任何合法的区间只能在墙内。所以我们记两个数组 \(len_i\):mex
为 \(i\) 时的最大答案,\(pre_i\):\(i\) 上一次出现的地方,那么就有 \(len_i=max(len_{a_i},i-pre_{a_i}-1)\)。
考虑满分做法,我们会发现若 \(a_i \neq b_i\) 是没有用的,因为若该区间 mex
为 \(a_i\),我们可以让这一位为 \(b_i\),同理若 mex
为 \(b_i\),这一位为 \(a_i\),对答案的计算毫无影响。所以我们只需要考虑 \(a_i = b_i\) 的位置,按 40% 的处理方法进行计算。
实现注意:
- 我们可以将最后一位视作一堵墙,记得把这个答案也更新在其中
Code 代码
int n,ans;
int a[N],b[N],pre[N],len[N];
int main(){
read(n);
for(rint i=1;i<=n;i++) read(a[i]);
for(rint i=1;i<=n;i++) read(b[i]);
for(rint i=1;i<=n;i++){
if(a[i]==b[i]){
len[a[i]]=max(len[a[i]],i-pre[a[i]]-1);
pre[a[i]]=i;
}
}
for(rint i=0;i<=n;i++) len[i]=max(len[i],n-pre[i]);//实现注意 1
for(rint i=0;i<=n;i++) ans=max(ans,len[i]-i);
printf("%d\n",ans);
return 0;
}