HDU 3397 Sequence operation

题目:下列操作

Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]

思路:  基础  区间 合并 不过操作比较多, 题目要求查询最长的 1  因为有异或  也要记下最长的  0

#include <iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#define N 100050
using namespace std;
int flag[N * 4], Xor[N * 4], sum[N * 4];
int a[N];
int lsum[2][N * 4], rsum[2][N * 4], msum[2][N * 4];
int max(int x, int y) {
    return x > y ? x : y;
}
void pushup(int i, int l, int r) {
    int mid = (l + r) >> 1;
    sum[i] = sum[i << 1] + sum[i << 1 | 1];
    for (int j = 0; j < 2; ++j) {
        lsum[j][i] = lsum[j][i << 1];
        rsum[j][i] = rsum[j][i << 1 | 1];
        if (lsum[j][i] == mid - l + 1)
            lsum[j][i] += lsum[j][i << 1 | 1];
        if (rsum[j][i] == r - mid)
            rsum[j][i] += rsum[j][i << 1];
        msum[j][i] = max(msum[j][i << 1], msum[j][i << 1 | 1]);
        msum[j][i] = max(msum[j][i], rsum[j][i << 1] + lsum[j][i << 1 | 1]);
    }
}
void pushdown(int i, int l, int r) {
    if (flag[i] != -1) {
        int mid = (l + r) >> 1;
        flag[i << 1] = flag[i << 1 | 1] = flag[i];
        Xor[i << 1] = Xor[i << 1 | 1] = 0;
        sum[i << 1] = (mid - l + 1) * flag[i];
        sum[i << 1 | 1] = (r - mid) * flag[i];
        lsum[flag[i]][i << 1] = rsum[flag[i]][i << 1] = msum[flag[i]][i << 1]
                = mid - l + 1;
        lsum[flag[i]][i << 1 | 1] = rsum[flag[i]][i << 1 | 1] = msum[flag[i]][i
                << 1 | 1] = r - mid;
        lsum[1 - flag[i]][i << 1] = rsum[1 - flag[i]][i << 1] = msum[1
                - flag[i]][i << 1] = 0;
        lsum[1 - flag[i]][i << 1 | 1] = rsum[1 - flag[i]][i << 1 | 1] = msum[1
                - flag[i]][i << 1 | 1] = 0;
        flag[i] = -1;

    }
    if (Xor[i] != 0) {
        int mid = (l + r) >> 1;
        Xor[i << 1] ^= 1;
        Xor[i << 1 | 1] ^= 1;
        sum[i << 1] = (mid - l + 1) - sum[i << 1];
        sum[i << 1 | 1] = (r - mid) - sum[i << 1 | 1];
        swap(lsum[0][i << 1], lsum[1][i << 1]);
        swap(rsum[0][i << 1], rsum[1][i << 1]);
        swap(msum[0][i << 1], msum[1][i << 1]);
        swap(lsum[0][i << 1 | 1], lsum[1][i << 1 | 1]);
        swap(rsum[0][i << 1 | 1], rsum[1][i << 1 | 1]);
        swap(msum[0][i << 1 | 1], msum[1][i << 1 | 1]);
        Xor[i] = 0;
    }
}

void build(int l, int r, int i) {
    flag[i] = -1;
    Xor[i] = 0;
    if (l == r) {
        sum[i] = flag[i] = a[l];
        msum[a[l]][i] = rsum[a[l]][i] = lsum[a[l]][i] = 1;
        msum[1 - a[l]][i] = rsum[1 - a[l]][i] = lsum[1 - a[l]][i] = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, i << 1);
    build(mid + 1, r, i << 1 | 1);
    pushup(i, l, r);
}
void update(int l, int r, int pl, int pr, int type, int i) {
    if (l >= pl && r <= pr) {
        if (type == 0) {
            flag[i] = 0;
            sum[i] = 0;
            Xor[i] = 0;
            lsum[0][i] = rsum[0][i] = msum[0][i] = r - l + 1;
            lsum[1][i] = rsum[1][i] = msum[1][i] = 0;
            return;
        }
        if (type == 1) {

            flag[i] = 1;
            sum[i] = (r-l+1);
            Xor[i] = 0;
            lsum[0][i] = rsum[0][i] = msum[0][i] = 0;
            lsum[1][i] = rsum[1][i] = msum[1][i] = r-l+1;
            return;
        }
        if(type==2)
        {
            Xor[i]^=1;
            sum[i]=(r-l+1)-sum[i];
            swap(lsum[0][i],lsum[1][i]);
            swap(rsum[0][i],rsum[1][i]);
            swap(msum[0][i],msum[1][i]);
            return;
        }
        return;
    }
    pushdown(i,l,r);
    int mid=(l+r)>>1;
    if(pl<=mid)update(l,mid,pl,pr,type,i<<1);
    if(pr>mid)update(mid+1,r,pl,pr,type,i<<1|1);
    pushup(i,l,r);
}
int query1(int l,int r,int pl,int pr,int i)
{
    if(l>=pl&&r<=pr)
        return sum[i];
    pushdown(i,l,r);
    int mid=(l+r)>>1;
    int tmp=0;
    if(pl<=mid)tmp+=query1(l,mid,pl,pr,i<<1);
    if(pr>mid)tmp+=query1(mid+1,r,pl,pr,i<<1|1);
    pushup(i,l,r);
    return tmp;
}

int query2(int l,int r,int pl,int pr,int i)
{
    if(l>=pl&&r<=pr)
    {
        return msum[1][i];
    }
    pushdown(i,l,r);
    int mid=(l+r)>>1;
    if(pr<=mid)return query2(l,mid,pl,pr,i<<1);
    else if(pl>mid)return query2(mid+1,r,pl,pr,i<<1|1);
    else
    {
        int tmp=0;
        if(mid-rsum[1][i<<1]+1>=pl)
            tmp+=rsum[1][i<<1];
        else
            tmp+=mid-pl+1;
        if(mid+lsum[1][i<<1|1]<=pr)
            tmp+=lsum[1][i<<1|1];
        else
            tmp+=pr-mid;

        int maxn1=query2(l,mid,pl,mid,i<<1);
        int maxn2=query2(mid+1,r,mid+1,pr,i<<1|1);
        tmp=max(tmp,maxn1);
        tmp=max(tmp,maxn2);
        return tmp;
    }
}
int main() {
    int n,m,tt;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;++i)
            scanf("%d",&a[i]);
        n--;
        build(0,n,1);
        

        while(m--)
        {
            int x,y,z;
            scanf("%d%d%d",&z,&x,&y);
            if(z<=2)update(0,n,x,y,z,1);
            else if(z==3)
            {

                printf("%d
",query1(0,n,x,y,1));
            }
            else
                printf("%d
",query2(0,n,x,y,1));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/L-Ecry/p/3886809.html