//generated by Gemini #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #include #include #include using namespace std; void solve() { int N, M; if (!(cin >> N >> M)) return; vector A(N + 1), B(M + 1); vector S_A(N + 1, 0), S_B(M + 1, 0); for (int i = 1; i <= N; ++i) { cin >> A[i]; S_A[i] = S_A[i - 1] + A[i]; } for (int j = 1; j <= M; ++j) { cin >> B[j]; S_B[j] = S_B[j - 1] + B[j]; } vector C(N + 1), D(M + 1); for (int i = 1; i <= N; ++i) cin >> C[i]; for (int j = 1; j <= M; ++j) cin >> D[j]; // 各インデックスの限界半径と、その半径まで広げたときの理論上最大ポテンシャル(Max)を前計算 vector limA(N + 1), limB(M + 1); vector MaxA(N + 1), MaxB(M + 1); for (int i = 1; i <= N; ++i) { limA[i] = min(i - 1, N - i); MaxA[i] = S_A[i + limA[i]] - S_A[i - 1 - limA[i]]; } for (int j = 1; j <= M; ++j) { limB[j] = min(j - 1, M - j); MaxB[j] = S_B[j + limB[j]] - S_B[j - 1 - limB[j]]; } // 色ごとにインデックスを分類 int max_color = N + M; vector> I(max_color + 1); vector> J(max_color + 1); for (int i = 1; i <= N; ++i) I[C[i]].push_back(i); for (int j = 1; j <= M; ++j) J[D[j]].push_back(j); long long ans = -1; for (int c = 1; c <= max_color; ++c) { if (I[c].empty() || J[c].empty()) continue; // 最大ポテンシャル (MaxA, MaxB) の降順にソートする sort(I[c].begin(), I[c].end(), [&](int a, int b) { return MaxA[a] > MaxA[b]; }); sort(J[c].begin(), J[c].end(), [&](int a, int b) { return MaxB[a] > MaxB[b]; }); for (int i : I[c]) { // 【最強の枝刈り1】 // i と、B側で最強のポテンシャルを持つ J[c][0] を組み合わせても ans 以下なら、 // これ以降の i は絶対に ans を超えられないため終了 if (MaxA[i] + MaxB[J[c][0]] <= ans) break; for (int j : J[c]) { // 【最強の枝刈り2】 // i と現在の j の理論上の最大値が ans 以下なら、 // これ以降の弱い j を見ても絶対に ans を超えられないため終了 if (MaxA[i] + MaxB[j] <= ans) break; int k = min(limA[i], limB[j]); long long sum = (S_A[i + k] - S_A[i - k - 1]) + (S_B[j + k] - S_B[j - k - 1]); if (sum > ans) { ans = sum; } } } } cout << ans << "\n"; } int main() { // 高速入出力 ios_base::sync_with_stdio(false); cin.tie(NULL); int T; if (cin >> T) { while (T--) { solve(); } } return 0; }