【题解】 CF1478E Nezzar and Binary String 线段树+时间逆序
Legend
Link \(\textrm{to Codeforces}\).
Editorial
觉得这个题很屑,来写个题解。
发现按时间逆序之后,等价于每次修改后要保证这个区间同色(正着做的话就不是同一个区间)。
因为一次只能修改小于 \(\frac{len}{2}\) 个数字,所以一定是修改成数量比较多的那种数字。
所以直接用线段树打区间覆盖维护区间和就行了。
特别地,区间查询发现如果 01 数量相同则输出 NO。
特别地,如果最终状态不符合初始状态也是 NO。
复杂度 \(O(q \log n + n)\)
Code
#include <bits/stdc++.h>
#define debug(...) fprintf(stderr ,__VA_ARGS__)
#define __FILE(x)\
freopen(#x".in" ,"r" ,stdin);\
freopen(#x".out" ,"w" ,stdout)
#define LL long long
const int MX = 2e5 + 23;
const LL MOD = 998244353;
int read(){
char k = getchar(); int x = 0;
while(k < '0' || k > '9') k = getchar();
while(k >= '0' && k <= '9') x = x * 10 + k - '0' ,k = getchar();
return x;
}
int L[MX] ,R[MX] ,n ,q;
char st[MX] ,ed[MX];
struct node{
int l ,r ,cov ,sum;
node *lch ,*rch;
}*root;
void docov(node *x ,int v){
x->cov = v;
x->sum = v * (x->r - x->l + 1);
}
void pushup(node *x){x->sum = x->lch->sum + x->rch->sum;}
void pushdown(node *x){if(~x->cov) docov(x->lch ,x->cov) ,docov(x->rch ,x->cov) ,x->cov = -1;}
node *build(int l ,int r){
node *x = new node; x->l = l ,x->r = r;
x->cov = -1 ,x->sum = 0;
if(l == r){
x->sum = ed[l] == '1';
x->lch = x->rch = nullptr;
}
else{
int mid = (l + r) >> 1;
x->lch = build(l ,mid);
x->rch = build(mid + 1 ,r);
pushup(x);
}return x;
}
int query(node *x ,int l ,int r){
if(l <= x->l && x->r <= r) return x->sum;
pushdown(x); int ans = 0;
if(l <= x->lch->r) ans += query(x->lch ,l ,r);
if(r > x->lch->r) ans += query(x->rch ,l ,r);
return ans;
}
void cover(node *x ,int l ,int r ,int v){
if(l <= x->l && x->r <= r) return docov(x ,v);
pushdown(x);
if(l <= x->lch->r) cover(x->lch ,l ,r ,v);
if(r > x->lch->r) cover(x->rch ,l ,r ,v);
return pushup(x);
}
bool check(node *x){
if(x->l == x->r) return x->sum == st[x->l] - '0';
pushdown(x);
return check(x->lch) && check(x->rch);
}
void solve(){
n = read() ,q = read();
scanf("%s" ,st + 1);
scanf("%s" ,ed + 1);
root = build(1 ,n);
for(int i = 1 ; i <= q ; ++i){
L[i] = read() ,R[i] = read();
}
for(int i = q ,one ,zero ; i ; --i){
one = query(root ,L[i] ,R[i]);
zero = R[i] - L[i] + 1 - one;
if(one == zero){
puts("NO");
return;
}
cover(root ,L[i] ,R[i] ,one > zero);
}
puts(check(root) ? "YES" : "NO");
}
int main(){
int T = read();
for(int i = 1 ; i <= T ; ++i){
solve();
}
return 0;
}