hdu 3911

题目

一直在用3397的现有代码去掉功能来代入这道题

但是莫名的TLE了。

于是按照网上大部分的方法,多维护了黑色的左,中,右最长连续

由于PushDown的时候忘记了把延迟标记传递下去,又贡献了几次WA

最后在输入加速和inline的帮助下,成功600ms AC


代码如下:

// 593ms

#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct Tree
{
    int l,r;
    int lazy;
    int lsum,msum,rsum;//white
    int lnum,mnum,rnum;//black
}tree[maxn<<2];

int num[maxn];

inline void PushUp(int rt)
{
    tree[rt].lsum=tree[rt<<1].lsum;
    tree[rt].rsum=tree[rt<<1|1].rsum;
    if(tree[rt].lsum==(tree[rt<<1].r-tree[rt<<1].l+1))
         tree[rt].lsum+=tree[rt<<1|1].lsum;
    if(tree[rt].rsum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))
         tree[rt].rsum+=tree[rt<<1].rsum;
    tree[rt].msum=max(tree[rt<<1].rsum+tree[rt<<1|1].lsum,max(tree[rt<<1].msum,tree[rt<<1|1].msum));

    tree[rt].lnum=tree[rt<<1].lnum;
    tree[rt].rnum=tree[rt<<1|1].rnum;
    if(tree[rt].lnum==(tree[rt<<1].r-tree[rt<<1].l+1))
         tree[rt].lnum+=tree[rt<<1|1].lnum;
    if(tree[rt].rnum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))
         tree[rt].rnum+=tree[rt<<1].rnum;
    tree[rt].mnum=max(tree[rt<<1].rnum+tree[rt<<1|1].lnum,max(tree[rt<<1].mnum,tree[rt<<1|1].mnum));
}

inline void PushDown(int rt)
{
    if(tree[rt].lazy){
        swap(tree[rt<<1].lsum,tree[rt<<1].lnum);
        swap(tree[rt<<1].rsum,tree[rt<<1].rnum);
        swap(tree[rt<<1].msum,tree[rt<<1].mnum);
        swap(tree[rt<<1|1].lsum,tree[rt<<1|1].lnum);
        swap(tree[rt<<1|1].rsum,tree[rt<<1|1].rnum);
        swap(tree[rt<<1|1].msum,tree[rt<<1|1].mnum);

        tree[rt<<1].lazy^=1;
        tree[rt<<1|1].lazy^=1;
        tree[rt].lazy^=1;

    }
}



inline void build(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    tree[rt].lazy=0;
    if(l==r) {
        if(num[l]){
            tree[rt].lsum=tree[rt].rsum=tree[rt].msum=1;
            tree[rt].lnum=tree[rt].rnum=tree[rt].mnum=0;

        }
        else{
            tree[rt].lsum=tree[rt].rsum=tree[rt].msum=0;
            tree[rt].lnum=tree[rt].rnum=tree[rt].mnum=1;
        }
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}


inline void update(int x,int y,int rt)
{
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    if(l==x&&r==y){
       swap(tree[rt].lnum,tree[rt].lsum);
       swap(tree[rt].rnum,tree[rt].rsum);
       swap(tree[rt].mnum,tree[rt].msum);
       tree[rt].lazy^=1;
       return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(x<=m) update(x,min(m,y),rt<<1);
    if(y>m) update(max(m+1,x),y,rt<<1|1);
    PushUp(rt);
}

inline int query(int x,int y,int rt)
{
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    if(l==x&&r==y){
        return tree[rt].msum;
    }
   PushDown(rt);
    int m=(l+r)>>1;
    if(y<=m) return query(x,y,rt<<1);
    else if(x>m) return query(x,y,rt<<1|1);
    else{
        int lr=query(x,m,rt<<1);
        int rr=query(m+1,y,rt<<1|1);
            return max(max(lr,rr),min(tree[rt<<1].rsum,tree[rt<<1].r-x+1)+min(tree[rt<<1|1].lsum,y-tree[rt<<1|1].l+1));
        }
}


inline int input()
{
    char c;
    int ret=0;
    c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar();
    return ret;
}


int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF){

    for(int i=1;i<=n;i++)
       num[i]=input();
    m=input();
    build(1,n,1);
    while(m--){
            int op,a,b;
            op=input();a=input();b=input();
            if(op==0)
                 printf("%d\n",query(a,b,1));
            else
                update(a,b,1);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值