CDOJ-1592 (2017 UESTC Training for Data Structures B)

Portal: CDOJ1592


Subject to the effect :

To give you a sequence of length n, only 1 and 0, m operations, two operations, the first section is a section of the exclusive-OR 0,

One for the interrogation interval period length of the longest continuous 1


Topic ideas:

This is the interval merged segment tree template title, each maintenance interval improvements in the general segment tree to the left to the right length of continuous 1's and 0's

And the length of the longest continuous interval, such as when updating the upward about equal subintervals continuous continuous continuous fill if left

Full subintervals, the opposite plus and continuous, such as continuous left interval length, the parent left section subintervals

Continuous Continuous, then the maximum consecutive subintervals about the maximum and intermediate successive subintervals continuous left and right sections of the left sub-plus

Down Update lazy recording marks, each consecutive 0's and 1 subintervals exchange, because it is the exclusive OR, 0 1,1 variable becomes 0,

When writing about the same update, query time will have to return the maximum and the maximum consecutive middle on both sides


AC Code:


/**
CDOJ1592 线段树区间合并模板题  HDU3911
*/


#include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define Max(a,b) (a)>(b)?(a):(b)
#define Min(a,b) (a)<(b)?(a):(b)
const int maxn = 1e5+100;

struct ST
{
    int lone,rone,lzero,rzero,sumone,sumzero;
    int cover;
    int l,r;
}Tree[maxn<<2];

int n;


//向上更新
void push_up(int rt)
{
    Tree[rt].lone = Tree[rt<<1].lone;
    Tree[rt].lzero = Tree[rt<<1].lzero;

    
    //子区间填满
    if(Tree[rt<<1].lone==Tree[rt<<1].r-Tree[rt<<1].l+1)Tree[rt].lone+=Tree[rt<<1|1].lone;
    if(Tree[rt<<1].lzero==Tree[rt<<1].r-Tree[rt<<1].l+1)Tree[rt].lzero+=Tree[rt<<1|1].lzero;

    Tree[rt].rone = Tree[rt<<1|1].rone;
    Tree[rt].rzero = Tree[rt<<1|1].rzero;

    if(Tree[rt<<1|1].rone==Tree[rt<<1|1].r-Tree[rt<<1|1].l+1)Tree[rt].rone+=Tree[rt<<1].rone;
    if(Tree[rt<<1|1].rzero==Tree[rt<<1|1].r-Tree[rt<<1|1].l+1)Tree[rt].rzero+=Tree[rt<<1].rzero;

    Tree[rt].sumone = max(Tree[rt<<1].rone+Tree[rt<<1|1].lone,max(Tree[rt<<1].sumone,Tree[rt<<1|1].sumone));
    Tree[rt].sumzero = max(Tree[rt<<1].rzero+Tree[rt<<1|1].lzero,max(Tree[rt<<1].sumzero,Tree[rt<<1|1].sumzero));
}

void Build(int l,int r,int rt)
{
    Tree[rt].l = l,Tree[rt].r = r,Tree[rt].cover = 0;
    if(l==r)
    {
        int x;scanf("%d",&x);
        Tree[rt].lone = Tree[rt].rone = Tree[rt].sumone = x;
        Tree[rt].lzero = Tree[rt].rzero = Tree[rt].sumzero = !x;
        return ;
    }
    int mid = (l+r)>>1;
    Build(lson);
    Build(rson);
    push_up(rt);
}

void pushdown(int rt)
{
    if(Tree[rt].cover)
    {
        Tree[rt<<1].cover^=1;
        Tree[rt<<1|1].cover^=1;
        Tree[rt].cover = 0;
        
        //0,1交换
        swap(Tree[rt<<1].lone,Tree[rt<<1].lzero);
        swap(Tree[rt<<1].sumone,Tree[rt<<1].sumzero);
        swap(Tree[rt<<1].rone,Tree[rt<<1].rzero);

        swap(Tree[rt<<1|1].lone,Tree[rt<<1|1].lzero);
        swap(Tree[rt<<1|1].sumone,Tree[rt<<1|1].sumzero);
        swap(Tree[rt<<1|1].rone,Tree[rt<<1|1].rzero);
    }
}

void updata(int l,int r,int rt)
{
    if(l<=Tree[rt].l&&Tree[rt].r<=r)
    {
        Tree[rt].cover^=1;
        swap(Tree[rt].lone,Tree[rt].lzero);
        swap(Tree[rt].sumone,Tree[rt].sumzero);
        swap(Tree[rt].rone,Tree[rt].rzero);
        return ;
    }
    pushdown(rt);
    int mid = (Tree[rt].r+Tree[rt].l)>>1;
    if(r<=mid)
    {
        updata(l,r,rt<<1);
    }
    else if(l>mid)
    {
       updata(l,r,rt<<1|1);
    }
    else
    {
        updata(l,mid,rt<<1);
        updata(mid+1,r,rt<<1|1);
    }
    push_up(rt);
}

int quary(int l,int r,int rt)
{
    if(l<=Tree[rt].l&&Tree[rt].r<=r)
    {
        return Tree[rt].sumone;
    }
    pushdown(rt);
    int mid = (Tree[rt].r+Tree[rt].l)>>1;
    if(l>mid)return quary(l,r,rt<<1|1);
    else if(r<=mid)return quary(l,r,rt<<1);
    else
    {
        int ans1 = quary(l,mid,rt<<1);
        int ans2 = quary(mid+1,r,rt<<1|1);
        return max(min(mid-l+1,Tree[rt<<1].rone)+min(r-mid,Tree[rt<<1|1].lone),max(ans1,ans2));
    }
}

int main()
{
    int m;
    while(cin>>n)
    {
        Build(1,n,1);
        cin>>m;
        while(m--)
        {
            int id,x,y;
            scanf("%d%d%d",&id,&x,&y);
            if(id)
            {
                updata(x,y,1);
            }
            else
            {
                printf("%d\n",quary(x,y,1));
            }
        }
    }

    return 0;
}







Published 110 original articles · won praise 76 · views 110 000 +

Guess you like

Origin blog.csdn.net/qq_34731703/article/details/74153766