汉中市疫情防控指挥部山东网络推广优化排名
分析:
赛时我是直接模拟的,tle然后mle,补提,发现规律,每一个改变的字符串都只会对应一个需要改变的区间,例如第一个样例前两个101100 -> 011100和101100 -> 011100,对应区间在确定改变的范围后可以发现是一样的,所以可以将给出的区间变成真正改变的区间,用set只存区间就可以了,对于找本质改变的区间,只有出现10这种序列才可以确定要改变,因此对于给定的l,r可以找从l开始向后遍历的第一个10,以及从r开始向前遍历的第一个10,得到的区间就是真正需要改变的区间,还有可能如果l.>r的时候,区间不存在,那么表示s本身,没有改变,也算一种新的字符串,也要存下来。
代码:
#include <bits/stdc++.h>using namespace std;
using ll = long long;int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);int T;cin >> T;while(T --){int n, m;cin >> n >> m;string s;cin >> s;s = " " + s;vector<int> l(n + 2, -1), r(n + 2, n + 2);for(int i = 1; i <= n; i ++) {l[i] = l[i - 1];if(s[i] == '0') l[i] = i;}for(int i = n; i >= 1; i --) {r[i] = r[i + 1];if(s[i] == '1') r[i] = i;}set<pair<int, int>> ans;while(m --) {int a, b;cin >> a >> b;if(r[a] <= l[b]) ans.insert({r[a], l[b]});else ans.insert({-1, -1});}cout << ans.size() << '\n';}
}