P8445 射命丸文的取材之旅

Question 问题 P8445 射命丸文的取材之旅

给定序列 { a n } , { b n } \{a_n\},\{b_n\} {an},{bn},求一个序列 { c n } \{c_n\} {cn} 满足 ∀ i ∈ [ 1 , n ] , c i ∈ { a i , b i } \forall i\in[1,n],c_i\in\{a_i,b_i\} i[1,n],ci{ai,bi},最大化

max ⁡ { r − l + 1 − mex ⁡ { c l , c l + 1 , … , c r − 1 , c r } } ( 1 ≤ l ≤ r ≤ n ) \max\{r-l+1-\operatorname{mex}\{c_l,c_{l+1},\dots, c_{r-1},c_r\}\}(1\le l\le r\le n) max{rl+1mex{cl,cl+1,,cr1,cr}}(1lrn)

并输出该式子可能的最大值。

Analysis 分析

这道题的提示有两个地方:

  1. 数据范围,40% 的数据中 a i = b i a_i = b_i ai=bi 直接把问题转换为给一个序列 { c n } \{c_n\} {cn} 求那个式子的最大值。
  2. 另一个是 mex 我们发现这玩意比较难处理,但是数据范围较小。

Solution

所以我们考虑枚举 mex 的值。设当前枚举的 mex t t t

考虑在 40% 的数据下,什么时候一个区间的 mex 不可为 t t t ,即区间内出现了 t t t 这个数。所以我们在当前枚举的情况下,将每一个 c i = t c_i = t ci=t 是为一个墙,(特别地, c n + 1 = t c_{n+1}=t cn+1=t )任何合法的区间只能在墙内。所以我们记两个数组 l e n i len_i lenimex i i i 时的最大答案, p r e i pre_i prei i i i 上一次出现的地方,那么就有 l e n i = m a x ( l e n a i , i − p r e a i − 1 ) len_i=max(len_{a_i},i-pre_{a_i}-1) leni=max(lenai,ipreai1)

考虑满分做法,我们会发现若 a i ≠ b i a_i \neq b_i ai=bi 是没有用的,因为若该区间 mex a i a_i ai,我们可以让这一位为 b i b_i bi,同理若 mex b i b_i bi,这一位为 a i a_i ai,对答案的计算毫无影响。所以我们只需要考虑 a i = b i a_i = b_i ai=bi 的位置,按 40% 的处理方法进行计算。

实现注意:

  1. 我们可以将最后一位视作一堵墙,记得把这个答案也更新在其中

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;
}

你可能感兴趣的:(算法)