题目大意:两个01串,q个询问,每次询问给定lr,串1lr内所有位置全为0或1,否则NO,询问后可以对lr内严格小于一半区间的字符进行修改,问q次询问过后,串1能否变为串2。
解题思路:逆转时间,串1变为串2变为串2变串1,这样的好处是,对于询问来说,可以先修改再保证区间全为0或1,接下来就模拟就好了,每次找区间内较少的字符,修改为另一个,最后比较一下修改后的串和串1是否相等就好了。这里注意是严格小于一半区间,所以当0和1数量相等时,NO。
1 #include<stdio.h> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn=2e5+5; 6 int t,n,q,q1[maxn],q2[maxn]; 7 int tree[maxn<<2],l[maxn<<2],r[maxn<<2],lazy[maxn<<2]; 8 char s1[maxn],s2[maxn]; 9 int cnt=0; 10 void build(int root,int ll,int rr){ 11 l[root]=ll;r[root]=rr; 12 lazy[root]=-1; 13 if(ll==rr){ 14 if(s2[++cnt]=='1') tree[root]=1; 15 else tree[root]=0; 16 return; 17 } 18 int mid=(ll+rr)/2; 19 build(root<<1,ll,mid); 20 build(root<<1|1,mid+1,rr); 21 tree[root]=tree[root<<1]+tree[root<<1|1]; 22 } 23 24 void push_down(int root){ 25 if(l[root]==r[root]) return ; 26 lazy[root<<1]=lazy[root]; 27 lazy[root<<1|1]=lazy[root]; 28 if(lazy[root]){ 29 tree[root<<1]=r[root<<1]-l[root<<1]+1; 30 tree[root<<1|1]=r[root<<1|1]-l[root<<1|1]+1; 31 }else { 32 tree[root<<1]=0; 33 tree[root<<1|1]=0; 34 } 35 lazy[root]=-1; 36 } 37 38 void updata(int root,int ll,int rr,int tmp){ 39 if(l[root]>=ll&&r[root]<=rr){ 40 if(tmp) 41 tree[root]=r[root]-l[root]+1; 42 else tree[root]=0; 43 lazy[root]=tmp; 44 return ; 45 } 46 if(lazy[root]!=-1) push_down(root); 47 int mid=(l[root]+r[root])/2; 48 if(mid<ll){ 49 updata(root<<1|1,ll,rr,tmp); 50 }else if(mid>=rr){ 51 updata(root<<1,ll,rr,tmp); 52 }else { 53 updata(root<<1,ll,rr,tmp); 54 updata(root<<1|1,ll,rr,tmp); 55 } 56 tree[root]=tree[root<<1]+tree[root<<1|1]; 57 } 58 59 int query(int root,int ll,int rr){ 60 if(ll<=l[root]&&rr>=r[root]){ 61 return tree[root]; 62 } 63 if(lazy[root]==0||lazy[root]==1){ 64 push_down(root); 65 } 66 int mid=(l[root]+r[root])/2; 67 if(mid<ll){ 68 return query(root<<1|1,ll,rr); 69 } else if(mid>=rr){ 70 return query(root<<1,ll,rr); 71 } else { 72 return query(root<<1,ll,rr)+query(root<<1|1,ll,rr); 73 } 74 } 75 76 int main() 77 { 78 scanf("%d",&t); 79 while(t--){ 80 int flag=1; 81 cnt=0; 82 scanf("%d%d",&n,&q); 83 scanf("%s%s",s1+1,s2+1); 84 build(1,1,n); 85 for(int i=q;i>=1;i--){ 86 scanf("%d %d",&q1[i],&q2[i]); 87 } 88 for(int i=1;i<=q;i++){ 89 int cnt1=query(1,min(q1[i],q2[i]),max(q1[i],q2[i])); 90 int cnt2=abs(q1[i]-q2[i])+1-cnt1; 91 if(cnt1==cnt2){ 92 flag=0; 93 break; 94 } else if(cnt1>cnt2){ 95 updata(1,min(q1[i],q2[i]),max(q1[i],q2[i]),1); 96 } else{ 97 updata(1,min(q1[i],q2[i]),max(q1[i],q2[i]),0); 98 } 99 } 100 for(int i=1;i<=n;i++){ 101 int tmp=query(1,i,i); 102 if(s1[i]-'0'!=tmp){ 103 flag=0;break; 104 } 105 } 106 if(flag){ 107 printf("YES\n"); 108 } else{ 109 printf("NO\n"); 110 } 111 } 112 return 0; 113 }View Code