题意:给定两个长为n (1leq nleq 10^6)的序列a,b,值域 ([1..n]) ,从这两个序列中个找出任意一对和相同的子序列(长度可以不同)
首先进行一个处理:若a的元素和大于b的元素和,则交换序列 a 和 b
令 A 表示序列a的前缀和数组 B表示序列b的前缀和数组 对于A中的每个元素 (A_i) ,B中一定存在 (B_j) 满足 (B_j geq A_i),我们找到最小的满足条件的 (B_j), 又因为值域在 ([1..n]) 内,所以 (0leq A_i-B_{j-1}< n)
([0,n)) 有 (n) 个数,但前缀和有 (n+1) 个(算上第0个),所以一定存在 (v, i_1, j_1, i_2, j_2) 满足 (A[i_1]-B[j_1]=A[i_2]-B[j_2]=v) 那么 a 中的 ([i_1,i_2]) 和 b 中的 ([j_1,j_2]) 两段的和一定相等
ll prea[MAXN], preb[MAXN];
pii g[MAXN];
void solve() {
int n = in;
fill(g, g+n+1, mp(-1,-1));
lop1(i, n) prea[i] = prea[i - 1] + ll(in);
lop1(i, n) preb[i] = preb[i - 1] + ll(in);
bool flag = 0;
if (prea[n] > preb[n]) swap(prea, preb), flag = 1;
lop0(i, n + 1) {
int v = upper_bound(preb, preb + 1 + n, prea[i]) - 1 - preb;
if (g[prea[i] - preb[v]] != mp(-1,-1)) {
int l = g[prea[i] - preb[v]].fi, L = g[prea[i] - preb[v]].se, r = i, R = v;
if (flag) swap(l, L), swap(r, R);
out, r - l, '
';
lop(i, l + 1, r) out, i, ' ';
puts("");
out, R - L, '
';
lop(i, L + 1, R) out, i, ' ';
return ;
}
g[prea[i] - preb[v]] = {i, v};
}
}