题意:
给出两个 01 01 01字符串 s , t s,t s,t ,对字符串 s s s有 q q q次查询,查询用区间 [ l , r ] [l,r] [l,r]表示,每次查询区间内的字符是否一致,若不一致,输出 N O NO NO ,反之则可以在查询完后修改这个区间内少于一半的字符,最后问能否使得字符串 s s s变为 t t t。
题解:
假如我们根据题目操作一步一步来,就会发现我们很难知道要修改哪些字符。因此正难则反,考虑倒推,看字符串 t t t能否变成字符串 s s s 。当我们倒着做,会发现修改操作先于查询操作,而查询操作要求区间内字符一样,也就意味着修改操作其实是固定了,即我们只能利用修改操作将此区间变为一致,而不能用于其他。
考虑怎么修改:线段树。利用线段树维护区间 01 01 01的个数。
1. 1. 1. 当区间 1 1 1的数量多于 0 0 0的数量时,我们就要把区间变为全 1 1 1
2. 2. 2.当区间 0 0 0的数量多于 1 1 1的数量时,我们就要把区间变为全 0 0 0
3.数量相等时,无法修改
最后判断 t t t是否等于 s s s即可
代码:
#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
char s1[MAXN],s2[MAXN];
int x[MAXN],y[MAXN];
struct node
{
int l,r;
int sum;
int lazy;
}node[MAXN<<2];
void push_up(int num){
node[num].sum=node[num<<1].sum+node[num<<1|1].sum;
}
void push_down(int num){
if(node[num].lazy!=-1){
node[num<<1].lazy=node[num<<1|1].lazy=node[num].lazy;
node[num<<1].sum=(node[num<<1].r-node[num<<1].l+1)*node[num].lazy;
node[num<<1|1].sum=(node[num<<1|1].r-node[num<<1|1].l+1)*node[num].lazy;
node[num].lazy=-1;
}
}
void build(int l,int r,int num){
node[num].l=l;
node[num].r=r;
node[num].lazy=-1;
if(l==r){
node[num].sum=s2[l]-'0';
return ;
}
int mid=(l+r)>>1;
build(l,mid,num<<1);
build(mid+1,r,num<<1|1);
push_up(num);
}
int query(int l,int r,int num){
if(node[num].l>=l&&node[num].r<=r){
return node[num].sum;
}
int sum=0;
push_down(num);
int mid=(node[num].l+node[num].r)>>1;
if(l<=mid){
sum+=query(l,r,num<<1);
}
if(r>mid){
sum+=query(l,r,num<<1|1);
}
return sum;
}
void updata(int l,int r,int val,int num){
if(node[num].l>=l&&node[num].r<=r){
node[num].sum=(node[num].r-node[num].l+1)*val;
node[num].lazy=val;
return;
}
push_down(num);
int mid=(node[num].l+node[num].r)>>1;
if(l<=mid){
updata(l,r,val,num<<1);
}
if(r>mid){
updata(l,r,val,num<<1|1);
}
push_up(num);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,q;
scanf("%d%d",&n,&q);
scanf("%s",s1+1);
scanf("%s",s2+1);
for(int i=1;i<=q;i++){
scanf("%d%d",&x[i],&y[i]);
}
build(1,n,1);
int flag=0;
for(int i=q;i>=1;i--){
int res1=query(x[i],y[i],1);
int res2=y[i]-x[i]+1-res1;
if(res1<res2) updata(x[i],y[i],0,1);
else if(res2<res1) updata(x[i],y[i],1,1);
else {flag=1;break;}
}
if(flag) printf("NO\n");
else{
for(int i=1;i<=n;i++){
int id=s1[i]-'0';
if(id!=query(i,i,1)){
flag=1;
break;
}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
}
}