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
");
        else
            printf("NO
");
    }
}
原文地址:https://www.cnblogs.com/zhanglichen/p/14346639.html