给定序列 { 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{r−l+1−mex{cl,cl+1,…,cr−1,cr}}(1≤l≤r≤n)
并输出该式子可能的最大值。
这道题的提示有两个地方:
mex
我们发现这玩意比较难处理,但是数据范围较小。所以我们考虑枚举 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 leni:mex
为 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,i−preai−1)。
考虑满分做法,我们会发现若 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% 的处理方法进行计算。
实现注意:
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;
}