zoukankan      html  css  js  c++  java
  • P2253 好一个一中腰鼓!

    题意:给你一个序列,初始是0,每次一个操作,把一个数^=1

       每次求出最长01串的长度

    正解:线段树(虽然暴力能过

       对于每个区间,记录三个值

       lmax,以l为首的01串长度

       rmax,以r为尾的01串长度

       mmax,既不以l又不以r为为端点的完全包在区间内的最长01串长度

    注意合并!

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define DB double
    bool turn[20505];
    struct node
    {
        node *ls;
        node *rs;
        int lmax;
        int rmax;
        int mmax;
        int l;
        int r;
        int len;
    };
    int n;
    int m;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline void push_up(node *now,int pos)
    {
        now->lmax=now->ls->lmax;                                      //最起码当前区间的lmax也得等于左儿子的lmax
        if(turn[pos]!=turn[pos+1]&&now->lmax==(now->ls->len))         //看左孩子右端和右孩子左端是否能接上&&lmax刚好为区间长度(全符合)
            now->lmax+=now->rs->lmax;                                 //接上
        now->rmax=now->rs->rmax;                                      //右孩子同理
        if(turn[pos]!=turn[pos+1]&&now->rmax==(now->rs->len))      
            now->rmax+=now->ls->rmax;
        now->mmax=max(now->ls->mmax,now->rs->mmax);                   //中间的先去max
        if(turn[pos]!=turn[pos+1])                                 
            now->mmax=max(now->mmax,now->ls->rmax+now->rs->lmax);     //考虑接上的情况
    }
    inline void build(node *now,int l,int r)
    {
        now->l=l;
        now->r=r;
        now->lmax=0;
        now->rmax=0;
        now->mmax=0;
        now->len=now->r-now->l+1;
        if(l==r)
        {
            now->lmax=1;
            now->rmax=1;  //最短为1
            now->mmax=1;
            return;
        }
        int mid=(l+r)>>1;
        now->ls=new node();
        now->rs=new node();
        build(now->ls,l,mid);
        build(now->rs,mid+1,r);
        push_up(now,mid);
    }
    inline void lazy(node *now,int k)
    {
        if(now->l>k||now->r<k) return;
        if(now->l==k&&now->r==k)
        {
            turn[now->l]^=1;   //到达叶子直接更新
            return;
        }
        lazy(now->ls,k);
        lazy(now->rs,k);
        push_up(now,(now->l+now->r)>>1);
    }
    signed main()
    {
        n=read();
        m=read();
        node *root=new node();
        build(root,1,n);
        while(m--)
        {
            lazy(root,read());
            put(max(root->lmax,max(root->rmax,root->mmax)));   //根(全序列)取max
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    Python编程-数据库
    Django框架之自定义分页
    Python编程-多线程
    Python编程-多进程二
    慕课学习--OSI与TCP/IP网络协议
    VMwaretools、共享文件夹、全屏
    Linux--慕课学习
    随想
    Linux--初次体验
    正则表达式——初次尝试
  • 原文地址:https://www.cnblogs.com/olinr/p/9574093.html
Copyright © 2011-2022 走看看