1478E.Nezzar and Binary String(线段树+逆序处理询问)
Nezzar希望将其长度为n的二进制字符串s与他的最好的朋友Nanako共享。 Nanako将花q天的时间检查二进制字符串。同时,Nezzar希望在这q天内将字符串s更改为字符串f,因为它看起来更好。
众所周知,菜菜子非常喜欢一致性。在第i天,Nanako将检查从位置li到位置ri的字符串s段。如果该段同时包含字符“ 0”和“ 1”,则Nanako会感到不满意并扔掉字符串。
经过检查后,在第i个晚上,Nezzar可以秘密地更改从li到ri(含)范围内的字符的严格少于一半的字符,否则更改将太明显。
现在,Nezzar想知道,是否有可能避免Nanako感到不快乐,同时在这q个昼夜中使字符串等于f。
比较常见的套路,比赛的时候顺利做出来了。
将所有询问离线后逆序处理即可。
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; typedef long long ll; int n,q,t; string s1; string s2; ll a[maxn];//s2中1的前缀和,0的前缀和反一下即可 struct node { int l,r; ll sum; ll lazy; }segTree[maxn*4]; void build (int i,int l,int r) { segTree[i].l=l; segTree[i].r=r; segTree[i].sum=0; segTree[i].lazy=-1; if (l==r) { segTree[i].sum=a[l]; return; } int mid=(segTree[i].l+segTree[i].r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum; } void spread (int i) { if (segTree[i].lazy!=-1) { segTree[i<<1].sum=(segTree[i<<1].r-segTree[i<<1].l+1)*segTree[i].lazy; segTree[i<<1].lazy=segTree[i].lazy; segTree[i<<1|1].sum=(segTree[i<<1|1].r-segTree[i<<1|1].l+1)*segTree[i].lazy; segTree[i<<1|1].lazy=segTree[i].lazy; segTree[i].lazy=-1; } } void add (int i,int l,int r,ll x) { if (segTree[i].l>=l&&segTree[i].r<=r) { segTree[i].sum=(segTree[i].r-segTree[i].l+1)*x; segTree[i].lazy=x; return; } spread(i); int mid=(segTree[i].l+segTree[i].r)>>1; if (l<=mid) add(i<<1,l,r,x); if (r>mid) add(i<<1|1,l,r,x); segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum; } ll query (int i,int l,int r) { if (segTree[i].l>=l&&segTree[i].r<=r) { return segTree[i].sum; } spread(i); int mid=(segTree[i].l+segTree[i].r)>>1; ll ans=0; if (l<=mid) ans+=query(i<<1,l,r); if (r>mid) ans+=query(i<<1|1,l,r); return ans; } int l[maxn],r[maxn]; int main () { scanf("%d",&t); while (t--) { scanf("%d%d",&n,&q); cin>>s1; cin>>s2; for (int i=1;i<=n;i++) a[i]=s2[i-1]-'0'; build(1,1,n); for (int i=1;i<=q;i++) { scanf("%d%d",l+i,r+i); } int f=1; for (int i=q;i>=1;i--) { int x=query(1,l[i],r[i]); int len=r[i]-l[i]+1; int y=len-x; if (x*2<len) { add(1,l[i],r[i],0); } else if (y*2<len) { add(1,l[i],r[i],1); } else { f=0; break; } } for (int i=1;i<=n;i++) { if (query(1,i,i)!=s1[i-1]-'0') f=0; } if (f) printf("YES\n"); else printf("NO\n"); } }