给定一个长度为 '+'、'-',第 '+' 表示 '-' 表示
D1 仅要求出最少删除多少个数字,D2 需要求出删除哪些数字(多解输出任意一组即可)。
先考虑没有多组询问。
窝萌首先发现一个性质,那就是如果有两个连续的相同字符,那么这两个字符对答案无贡献,我们可以直接删掉。那我们一次删掉之后,最后得到的序列只能是正负交替的了。于是我们只要考虑此种情况即可。我们发现如果删完的序列长度为奇数的话,我们只要删除最中间那个数就可以了。我们考虑偶数,如果长度已经为
于是我们发现,如果是询问系列长度为奇数,那答案最多是
这样 D1 就做完了。
我们考虑 D2,我们先考虑奇数的情况,我们假设要删掉的数是第 set,之后对每组询问 lower_bound 出一个在
长度为偶数就直接随便删掉最左边或是最右边的数,然后按照奇数的方法做即可。
cpp
const int maxn = 300005;
int qzh[maxn];
char s[maxn];
void solve() {
int n, q;
scanf("%d%d%s", &n, &q, s + 1);
std::map<int, std::set<int>> mp;
for (int i = 1; i <= n; ++i) {
qzh[i] = qzh[i - 1] + (((i & 1) == (s[i] == '+')) ? 1 : -1);
mp[qzh[i - 1] + qzh[i]].insert(i);
}
while (q--) {
int l, r;
scanf("%d%d", &l, &r);
if (qzh[r] - qzh[l - 1]) {
if ((r - l) & 1) {
puts("2");
writesp(r);
r--;
} else {
puts("1");
}
writeln(*mp[qzh[l - 1] + qzh[r]].lower_bound(l));
} else {
puts("0");
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}