Codeforces Round #698 (Div. 1) B. Nezzar and Binary String (线段树)

题目链接:https://codeforces.com/contest/1477/problem/B

B. Nezzar and Binary String

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Nezzar has a binary string ss of length nn that he wants to share with his best friend, Nanako. Nanako will spend qq days inspecting the binary string. At the same time, Nezzar wants to change the string ss into string ff during these qq days, because it looks better.

扫描二维码关注公众号,回复: 12638598 查看本文章

It is known that Nanako loves consistency so much. On the ii-th day, Nanako will inspect a segment of string ss from position lili to position riri inclusive. If the segment contains both characters '0' and '1', Nanako becomes unhappy and throws away the string.

After this inspection, at the ii-th night, Nezzar can secretly change strictly less than half of the characters in the segment from lili to riri inclusive, otherwise the change will be too obvious.

Now Nezzar wonders, if it is possible to avoid Nanako being unhappy and at the same time have the string become equal to the string ff at the end of these qq days and nights.

Input

The first line contains a single integer tt (1≤t≤2⋅1051≤t≤2⋅105) — the number of test cases.

The first line of each test case contains two integers n,qn,q (1≤n≤2⋅1051≤n≤2⋅105, 0≤q≤2⋅1050≤q≤2⋅105).

The second line of each test case contains a binary string ss of length nn.

The third line of each test case contains a binary string ff of length nn.

Then qq lines follow, ii-th of them contains two integers li,rili,ri (1≤li≤ri≤n1≤li≤ri≤n)  — bounds of the segment, that Nanako will inspect on the ii-th day.

It is guaranteed that the sum of nn for all test cases doesn't exceed 2⋅1052⋅105, and the sum of qq for all test cases doesn't exceed 2⋅1052⋅105.

Output

For each test case, print "YES" on the single line if it is possible to avoid Nanako being unhappy and have the string ff at the end of qq days and nights. Otherwise, print "NO".

You can print each letter in any case (upper or lower).

Example

input

Copy

4
5 2
00000
00111
1 5
1 3
2 1
00
01
1 2
10 6
1111111111
0110001110
1 10
5 9
7 10
1 7
3 5
6 10
5 2
10000
11000
2 5
1 3

output

Copy

YES
NO
YES
NO

Note

In the first test case, 00000––––––→000––––11→0011100000_→000_11→00111 is one of the possible sequences of string changes.

In the second test case, it can be shown that it is impossible to have the string ff at the end.

题目大意:输入一个长度为n(1<=n<=2*10^{5})的01字符串s1,有q天,每一天的白天都需要检查字符串的区间[l_{i},r_{i}]是否为全0或者全1,晚上可以修改区间[l_{i},r_{i}]严格小于一半的字符。要求每天白天都通过检查,并且最后变为目标串s2是否可行。

题解:若从初始串s1开始推导,某一天可以进行多种可能的操作,而且对后面有很大的影响,很难进行推导和判断。但是如果我们反过来,从目标串s2开始,从最后一天开始往前推导,对于每一天的区间[l_{i},r_{i}],由于只能修改小于一半的字符,我们要么只能修改为全1,要么只能修改为全0,要么要修改刚好一半的字符这时就不能成功。每一天的操作都是固定的,推到第一天后判断和初始串是否相同就行了。对于每一天的操作要么把区间覆盖为全0,要么覆盖为全1。我们可以用线段树来进行维护。

复杂度n*logn

代码如下:

#include<bits/stdc++.h>

using namespace std;
const int nn =210000;
const int inff = 0x3fffffff;
const double eps = 1e-8;
typedef long long LL;
const double pi = acos(-1.0);
const LL mod = (479 << 21) + 1;
string s;
string targetS;
int tl[nn*20],tr[nn*20],sum[nn*20],lz[nn*20];
int n,q;
void build(int i,int l,int r)
{
    tl[i] = l;
    tr[i] = r;
    lz[i] = -1;
    if(l==r)
    {
        sum[i] = targetS[l-1]-'0';
        return;
    }
    int mid = (l+r)/2;
    build(i*2,l,mid);
    build(i*2+1,mid+1,r);
    sum[i] = sum[2*i]+sum[2*i+1];
}
void push_down(int i)
{
    if(lz[i]!=-1)
    {
        lz[2*i]=lz[2*i+1]=lz[i];
        sum[2*i] = lz[i]*(tr[2*i]-tl[2*i]+1);
        sum[2*i+1] = lz[i]*(tr[2*i+1]-tl[2*i+1]+1);
        lz[i]=-1;
    }
}
int Sum(int i,int l,int r)
{
    if(tl[i]>=l&&tr[i]<=r)
    {
        return sum[i];
    }
    push_down(i);
    int ret=0;
    int mid = (tl[i]+tr[i])/2;
    if(l<=mid)
        ret += Sum(i*2,l,r);
    if(r>mid)
        ret += Sum(i*2+1,l,r);
    return ret;
}
void Change(int i,int l,int r,int value)
{
    if(tl[i]>=l&&tr[i]<=r)
    {
        sum[i]=value*(tr[i]-tl[i]+1);
        lz[i]=value;
        return;
    }
    push_down(i);
    int mid = (tl[i]+tr[i])/2;
    if(l<=mid)
        Change(i*2,l,r,value);
    if(r>mid)
        Change(i*2+1,l,r,value);
    sum[i] = sum[2*i]+sum[2*i+1];
}
int inputL[nn],inputR[nn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>q;
        cin>>s;
        cin>>targetS;
        build(1,1,n);
        bool ans =true;
        for(int i=0;i<q;i++)
        {
            cin>>inputL[i]>>inputR[i];
        }
        for(int i=q-1;i>=0;i--)
        {
            int sumlr = Sum(1,inputL[i],inputR[i]);
            if(sumlr*2>(inputR[i]-inputL[i]+1))
            {
                Change(1,inputL[i],inputR[i],1);
            } else if(sumlr*2<(inputR[i]-inputL[i]+1)) {
                Change(1,inputL[i],inputR[i],0);
            } else {
                ans = false;
            }
        }
        if(ans) {
            for(int i=0;i<n;i++)
            {
                if(Sum(1,i+1,i+1)!=s[i]-'0')
                {
                    ans = false;
                    break;
                }
            }
        }
        if(ans)
        {
            puts("YES");
        }else{
            puts("NO");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/madaidao/article/details/114229275