CF2117E 题解

· · 题解

前言

目前的题解都是只说结论,我来证明一下。
首先,观察题面:
可以进行一次删除操作。
选取 i,然后使得 a_i = b_{i + 1}b_i = a_{i + 1}

结论

a_n = b_n 时,答案为 n
否则,答案为最大的下标 i 满足 a_i = b_ia_i = a_{i + 1}b_i = b_{i + 1}a_i(b_i)i + 1 (不包括 i + 1)后出现过。

证明

情况 1:有一个下标 i 使得 a_i = b_i
此时我们可以交替赋值:

情况 $2$:有一个下标 $i$ 使得 $a_i = a_{i + 1}(b_i = b_{i + 1})$。 赋值一次就变成情况 $1$ 了。 情况 $3$:$a_i(b_i)$ 在 $i + 1$ 的后面(不包括 $i + 1$)出现过。 分讨。假设出现过的这个数的下标为 $j$。 1. $a_i = a_j(b_i = b_j)$,$j - i + 1$ 为偶数。手推一下,发现此时不断赋值最终会变成情况 $1$。 2. $a_i = a_j(b_i = b_j)$,$j - i + 1$ 为奇数。怎么办呢?别忘了,还有一个条件没用:**可以进行一次删除操作。** 于是我们进行一次删除操作,$j - i + 1$ 就变成偶数了。 3. $a_i = b_j(b_i = a_j)$,$j - i + 1$ 为奇数。仍然是不断赋值。 4. $a_i = b_j(b_i = a_j)$,$j - i + 1$ 为偶数。**可以进行一次删除操作。** 仍然是删除一次,$j - i + 1$ 就变成奇数了。 这时有人就要问了:为什么是 $i + 1$ 的后面而不是 $i$ 的后面呢? 如果是 $i$ 的后面(不包括 $i$),那么 1. 和 2. 在 $j = i + 1$ 情况下就是情况 $2$,3. 在 $j = i + 1$ 情况下不满足 $j - i + 1$ 为奇数,4. 在 $j = i + 1$ 情况下无解,所以还是相当于在 $i + 1$ 的后面,还得做特判,过于麻烦。 ### 代码 ```cpp #include <bits/stdc++.h> using namespace std; #define ll long long #define endl "\n" ll T, n, a[200010], b[200010]; bool vis[200010]; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> T; while(T--){ memset(vis, 0, sizeof vis); cin >> n; for(ll i = 1; i <= n; i++) cin >> a[i]; for(ll i = 1; i <= n; i++) cin >> b[i]; if(a[n] == b[n]){ cout << n << endl; continue; } ll mx = 0; for(ll i = n - 1; i > 0; i--){ if(a[i] == b[i] || a[i + 1] == a[i] || b[i + 1] == b[i] || vis[a[i]] || vis[b[i]]){ mx = i; break; } vis[a[i + 1]] = vis[b[i + 1]] = 1; } cout << mx << endl; } return 0; } ``` [提交记录 $326213467$](https://codeforces.com/problemset/submission/2117/326213467) 码字不易,求赞 qwq。