zoukankan      html  css  js  c++  java
  • bzoj1858[Scoi2010]序列操作

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1858

    十分普通的线段树。调了好久……

    记录一下0的信息,在reverse的时候比较方便。

    1.把修改和pushdown里要用到的东西都写在一个函数里比较方便。别忘了改标记。

      一开始没有把改标记写在那个函数里,结果忘了在pushdown的时候下传rev的标记。

    2.修改操作很简单。可以把标记规定成rev和b不同时存在、b[0]和b[1]不同时存在,就很好了。

    3.三目运算符要整个括起来。

    4.rev标记是^=1。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1e5+5;
    int n,m,tot=1,L,R;
    bool c[N];
    struct Node{
        int ls,rs,cd;
        bool b[2],rev;
        int l[2],r[2],len[2],sum;
    }a[N<<1];
    int rdn()
    {
        int ret=0;char ch=getchar();
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch<='9'&&ch>='0')(ret*=10)+=ch-'0',ch=getchar();
        return ret;
    }
    void pushup(int cr)
    {
        int ls=a[cr].ls,rs=a[cr].rs;
        a[cr].sum=a[ls].sum+a[rs].sum;
        for(int d=0;d<=1;d++)
        {
            a[cr].l[d]=a[ls].l[d]+(a[ls].l[d]==a[ls].cd?a[rs].l[d]:0);//括起来 
            a[cr].r[d]=a[rs].r[d]+(a[rs].r[d]==a[rs].cd?a[ls].r[d]:0);
            a[cr].len[d]=max(max(a[ls].len[d],a[rs].len[d]),a[ls].r[d]+a[rs].l[d]);
        }
    }
    void build(int l,int r,int cr)
    {
        a[cr].cd=r-l+1;
        if(l==r){
            a[cr].l[c[l]]=a[cr].r[c[l]]=a[cr].len[c[l]]=1;
            a[cr].sum=c[l];return;
        }
        int mid=((l+r)>>1);
        a[cr].ls=++tot;build(l,mid,tot);
        a[cr].rs=++tot;build(mid+1,r,tot);
        pushup(cr);
    }
    void mdf(int k,int d)
    {
        a[k].b[d]=1;a[k].b[!d]=0;a[k].rev=0;//b[0]和b[1]不同时存在 
        a[k].sum=a[k].cd*d;
        a[k].len[d]=a[k].l[d]=a[k].r[d]=a[k].cd;
        a[k].len[!d]=a[k].l[!d]=a[k].r[!d]=0;
    }
    void rv(int k)
    {
        a[k].rev^=1;//和mdf一样,把下传标记写在函数里 且是^=1 
        if(a[k].b[0]||a[k].b[1])a[k].rev=0,swap(a[k].b[0],a[k].b[1]);//rev和b不同时存在 
        a[k].sum=a[k].cd-a[k].sum;swap(a[k].len[1],a[k].len[0]);
        swap(a[k].l[0],a[k].l[1]);swap(a[k].r[0],a[k].r[1]);
    }
    void pushdown(int cr)
    {
        if(!a[cr].ls)return;
        int ls=a[cr].ls,rs=a[cr].rs;
        if(a[cr].rev)
            {a[cr].rev=0;rv(ls);rv(rs);a[cr].rev=0;}
        if(a[cr].b[0]||a[cr].b[1])
            {int d=a[cr].b[1];a[cr].b[d]=0;mdf(ls,d);mdf(rs,d);}
    }
    void mdfy(int l,int r,int cr,int d)
    {
        if(l>=L&&r<=R){mdf(cr,d);return;}
        pushdown(cr);
        int mid=((l+r)>>1);
        if(mid>=L)mdfy(l,mid,a[cr].ls,d);
        if(mid<R)mdfy(mid+1,r,a[cr].rs,d);
        pushup(cr);
    }
    void rever(int l,int r,int cr)
    {
        if(l>=L&&r<=R){
            rv(cr);return;
        }
        pushdown(cr);
        int mid=((l+r)>>1);
        if(mid>=L)rever(l,mid,a[cr].ls);
        if(mid<R)rever(mid+1,r,a[cr].rs);
        pushup(cr);
    }
    int query(int l,int r,int cr)
    {
        if(l>=L&&r<=R)return a[cr].sum;
        pushdown(cr);
        int mid=((l+r)>>1),ret=0;
        if(mid>=L)ret+=query(l,mid,a[cr].ls);
        if(mid<R)ret+=query(mid+1,r,a[cr].rs);
        return ret;
    }
    int lnk(int l,int r,int cr)
    {
        if(l>=L&&r<=R)return a[cr].len[1];
        pushdown(cr);
        int mid=((l+r)>>1),ls=a[cr].ls,rs=a[cr].rs;
        if(mid<L)return lnk(mid+1,r,rs);
        if(mid>=R)return lnk(l,mid,ls);
        int tp=min(a[ls].r[1],mid-L+1)+min(a[rs].l[1],R-mid);
        return max(max(lnk(l,mid,ls),lnk(mid+1,r,rs)),tp);//
    }
    int main()
    {
        n=rdn();m=rdn();for(int i=1;i<=n;i++)c[i]=rdn();
        build(1,n,1);int op;
        while(m--)
        {
            op=rdn();L=rdn()+1;R=rdn()+1;
            if(op<=1)mdfy(1,n,1,op);
            if(op==2)rever(1,n,1);
            if(op==3)printf("%d
    ",query(1,n,1));
            if(op==4)printf("%d
    ",lnk(1,n,1));
        }
        return 0;
    }
  • 相关阅读:
    unity vscode 断点问题
    unity Prefab 序列化一个小问题。
    公司有同事中病毒
    有点愧疚,今天把unity官方骗了...
    网络处理,发送约定
    (转载)MonoBehaviour的事件和具体功能总结
    控制台输出乱码问题
    vs遇到的字符串问题
    cmake的下载和安装
    三消设计思路, 通过配置文件搞定一切。
  • 原文地址:https://www.cnblogs.com/Narh/p/9188919.html
Copyright © 2011-2022 走看看