CF1478E Nezzar and Binary String

原题链接

描述

有两个个长为n的 0-1 串 \(s,f\),有 q 次查询,每次查询一个区间 \([l,r]\),每次查询要求区间里的数全是 0 或者全是 1。每次查询后都可以修改 [l,r] 区间内严格小于区间长度的字符,问经过 n 次查询和修改后,是否满足 s 能转化到 f。

思路

逆序思考,最后一次查询后,[l,r] 区间内肯定全是 0 或 1。那么根据 f 我们可以知道前面一个未修改的状态,由此我们可以逆推到第一个字符串,判断其是否等于 s 即可,用线段树维护区间内 1 的个数,和区间赋值操作即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
struct Node{
    int l,r;
    int sum,lazy;
}tr[N*4];
char s[N],f[N];
void pushup(int u){
    tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void pushdown(int u){
    if(tr[u].lazy){
        int k=tr[u].lazy;
        if(k==1){
            tr[u<<1].sum=(tr[u<<1].r-tr[u<<1].l+1);
            tr[u<<1|1].sum=(tr[u<<1|1].r-tr[u<<1|1].l+1);
        }else{
            tr[u<<1].sum=tr[u<<1|1].sum=0;
        }
        tr[u<<1].lazy=tr[u<<1|1].lazy=k;
    }   
    tr[u].lazy=0;
}
void build(int u,int l,int r){
    if(l==r) {
        tr[u]={l,r,f[l]-'0',0};
    }else{
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
        tr[u].l=l; tr[u].r=r;
        tr[u].lazy=0;
    }
}
void modify(int u,int l,int r,int d){
    if(l<=tr[u].l && r>=tr[u].r) {
        if(d==1){
            tr[u].sum=tr[u].r-tr[u].l+1;
            tr[u].lazy=1;
        }else{
            tr[u].sum=0;
            tr[u].lazy=-1;
        }
    }else{
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(mid>=l) modify(u<<1,l,r,d);
        if(mid+1<=r) modify(u<<1|1,l,r,d);
        pushup(u);
    }
}
int query(int u,int l,int r){
    if(l<=tr[u].l && r>=tr[u].r) {
        return tr[u].sum;
    }else{
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        int sum=0;
        if(mid>=l) sum=query(u<<1,l,r);
        if(mid+1<=r) sum+=query(u<<1|1,l,r);
        return sum;
    }
}
bool check(int u){    
    int l=tr[u].l,r=tr[u].r;
    if(l==r) {
        return tr[u].sum==s[l]-'0';
    }else{
        pushdown(u);
        return check(u<<1)&check(u<<1|1);
    }
}
int main(){
    int t; cin>>t; for(int x=1;x<=t;x++){
        int n,q;  scanf("%d%d%s%s",&n,&q,s+1,f+1);
        build(1,1,n);
        vector<array<int,2>> v(q);
        for(int i=0;i<q;i++){
            int l,r; scanf("%d%d",&l,&r);
            v[i]={l,r};
        }
        bool flag=true;
        for(int i=q-1;i>=0;i--){
            int l=v[i][0],r=v[i][1];
            int t=query(1,l,r);
            int tt=r-l+1-t;
            if(t==tt){flag=false; break;}
            if(t<tt) modify(1,l,r,-1);
            else modify(1,l,r,1);
        }
        if(flag) flag=check(1);
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}
posted @ 2021-01-31 16:23  ans20xx  阅读(104)  评论(0)    收藏  举报