The total matching score can be calculated in two parts:
Brute-forcing all $K$ rotations takes $O(K^2)$, which is too slow. We need $O(K)$.
Key Insight: If number $X$ matches after rotation $R$, then their original index difference $Index_B(X) - Index_A(X)$ must correspond to $R$.
Count the frequency of each position difference (Frequency Map). The highest frequency indicates the best rotation.
#include
using namespace std;
typedef long long ll;
int n, k;
int a[500005], b[500005], seen[500005];
int pos[500005]; // 1-based index storage for Array A
int ans; // Count of items outside both cycles
// Core Logic: Calculate max matches for fixed orientation
int solve() {
vector v;
v.resize(k+1, 0); // Frequency bucket for shifts
for (int i = 1; i <= k; i++) {
if (pos[b[i]] == 0) continue; // Item in B not found in A
int d = i - pos[b[i]]; // Calculate shift difference
if (d < 0) d += k; // Handle circular wrap-around
v[d]++;
}
// Return the shift with the highest frequency
return *max_element(v.begin(), v.end());
}
int main() {
scanf("%d %d", &n, &k);
// Read A and mark seen
for (int i = 1; i <= k; i++) {
scanf("%d", &a[i]);
seen[a[i]] = 1;
}
// Read B and mark seen
for (int i = 1; i <= k; i++) {
scanf("%d", &b[i]);
seen[b[i]] = 1;
}
// Part 1: Count items NOT in either cycle (Always valid)
for (int i = 1; i <= n; i++)
if (!seen[i]) ans++;
// Precompute positions of elements in A for O(1) lookup
for (int i = 1; i <= k; i++)
pos[a[i]] = i;
// Part 2: Solve for original direction
int ans0 = solve();
// Part 3: Solve for reversed direction
reverse(b+1, b+k+1);
int ans1 = solve();
// Final Answer = Outside + Max(Inside_Original, Inside_Reversed)
printf("%d\n", ans + max(ans0, ans1));
return 0;
}
The core of this problem is transforming the "rotation matching" problem into a "relative position difference frequency" problem.
This technique is very common when dealing with circular arrays or periodic string matching problems.