思路:从逆向想一下,发现最后得到的一定是最后的字符串f,然后往前推,因为只能改变<len/2的元素,不难发现改变已经定下来了,即只能全改为数量大的那个字符,如果长度为偶数两种字符相等则不能达成。维护和查找用线段树覆盖。
down的一个修改
Code:
#include<iostream>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
using namespace std;
struct node
{
ll l, r, f, w;
}tree[5000005];
inline void build(int k, int ll, int rr)
{
tree[k].l = ll, tree[k].r = rr, tree[k].f = -1;
if (tree[k].l == tree[k].r) { char ch;cin >> ch;tree[k].w=ch-'0'; return; }
int mid = (tree[k].l + tree[k].r) / 2;
build(2 * k, ll, mid);
build(2 * k + 1, mid + 1, rr);
tree[k].w = tree[2 * k].w + tree[2 * k + 1].w;
}
inline void down(int k)
{
if (tree[k].f == -1)return;//表示此时f为无效状态
tree[2 * k].f = tree[k].f;
tree[2 * k + 1].f = tree[k].f;
tree[2 * k].w = tree[k].f * (tree[2 * k].r - tree[2 * k].l + 1);//直接让后面的值等于f
tree[2 * k + 1].w = tree[k].f * (tree[2 * k + 1].r - tree[2 * k + 1].l + 1);
tree[k].f = -1;//给儿子赋值后再变为无效状态
}
inline ll ask_interval(int k, int x, int y)
{
ll ans = 0;
if (x <= tree[k].l && y >= tree[k].r)
{
return tree[k].w;
}
down(k);
int mid = (tree[k].l + tree[k].r) / 2;
if (x <= mid)ans += ask_interval(2 * k, x, y);
if (y > mid)ans += ask_interval(2 * k + 1, x, y);
return ans;
}
inline void change_interval(int k, int x, int y, int add)
{
if (x <= tree[k].l && y >= tree[k].r)
{
tree[k].w = add * (tree[k].r - tree[k].l + 1);
tree[k].f = add;
return;
}
down(k);
int mid = (tree[k].l + tree[k].r) / 2;
if (x <= mid)change_interval(2 * k, x, y, add);
if (y > mid)change_interval(2 * k + 1, x, y, add);
tree[k].w = tree[2 * k].w + tree[2 * k + 1].w;
}
const int Max = 1e6 + 5;
int a[Max], b[Max], q[Max][2];
int main()
{
FAST;
int t;cin >> t;
while (t--)
{
int n, qq;cin >> n >> qq;
for (int i = 1;i <= n;i++)
{
char c;cin >> c;
a[i] = c - '0';
}
build(1, 1, n);
for (int i = 1;i <= qq;i++)cin >> q[i][0] >> q[i][1];
int f = 1;
for (int i = qq;i >=1 ;i--)
{
int l = q[i][0], r = q[i][1];
int sum = ask_interval(1, l, r);
if ((r - l+1) % 2 == 0 && sum == (r - l + 1) / 2) {
f = 0;
}
if (sum <= (r - l + 1) / 2)change_interval(1, l, r, 0);
else change_interval(1, l, r, 1);
}
for (int i = 1;i <= n;i++)
{
int g = ask_interval(1, i, i);
if (a[i] != g)f = 0;
}
if (f)cout << "YES" << endl;
else cout << "NO" << endl;
}
}