zoukankan      html  css  js  c++  java
  • 西安段素

    题目是我自己起的

    好久之前做的了。

    现在又有人讲介个东西

    拿出来做做样子吧。

    P2253 好一个一中腰鼓!
    然而这题数据水。所以评级也不高。

    #include<iostream> 
    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    struct node//线段树结构体
    {
        int lf;//从左开始的连续子段长度  l:left
        int mf;//在区间内部的连续子段长度 m:mid
        int rf;//以右端点结束的连续子段的长度 r:right下同
    };
    node t[70100];//线段树数组
    int turn[2]={1,0};//转变数组,也可以自己if
    int base[70100];//记录是否被反转过,0为无,1为有
    void push(int &root,int &l,int &r,int &m)
    {
        int ls=root<<1;//left son
        int rs=(root<<1)|1;//right son
        t[root].lf=t[ls].lf;//大区间的左端点开始的连续子段最起码是左区间以左区间左端点开头的连续子段
        if(base[m]!=base[m+1]&&m-l+1==t[ls].lf) //如果左区间整个都是连读的
            t[root].lf+=t[rs].lf;//在将右区间的以右区间开头的连续子段长度加上,下同
        t[root].rf=t[rs].rf;//处理大区间以右端点结尾的连续子段长度
        if(base[m]!=base[m+1]&&r-m==t[rs].rf) 
            t[root].rf+=t[ls].rf;
        t[root].mf=max(t[ls].mf,t[rs].mf);//在大区间内的连续子段,这一步请类比分支
        if(base[m]!=base[m+1])//左右区间拼接
            t[root].mf=max(t[root].mf,t[ls].rf+t[rs].lf);
        return ;
    }
    void build(int root,int l,int r)
    {
        if(l==r)//叶子节点的初状态
        {
            t[root].lf=1;
            t[root].mf=1;
            t[root].rf=1;
            return ;
        }
        int mid=(l+r)>>1;
        build(root<<1,l,mid);
        build((root<<1)|1,mid+1,r);
        push(root,l,r,mid);//用他两个儿子更新自己,这里用作初始化
        return ;
    }
    void updata(int root,int l,int r,int a)
    {
        if(l>a||r<a)
            return ;
        if(l==a&&r==a)
        {
            base[l]=turn[base[l]];
            return ;//更改
        }
        int mid=(l+r)>>1;
        updata(root<<1,l,mid,a);
        updata((root<<1)|1,mid+1,r,a);
        push(root,l,r,mid);//维护线段树
        return ;
    }
    int main()
    {
        int n,m;//输入不解释
        scanf("%d%d",&n,&m);
        build(1,1,n);
        int a;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a);
            updata(1,1,n,a);
            printf("%d
    ",max(t[1].lf,max(t[1].mf,t[1].rf)));//手动max
        }
    }
    
  • 相关阅读:
    代码注释技术
    疑难杂症错误解决方法大全
    MD5 加密
    ADO.NET DataReader和DataAdapter的区别
    HTTP协议详解
    web开发常用样式
    Stream 和 byte[] 之间的转换
    Sql 函数大全 (更新中...由难到简
    Web C# 导出Excel 方法总结
    VC++ MFC 如何实现在编辑框中输出具有换行功能的文段 01
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9130024.html
Copyright © 2011-2022 走看看