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;
    }
  • 相关阅读:
    MIne FirstBlog
    P6563 [SBCOI2020]一直在你身旁
    P6563 [SBCOI2020]一直在你身旁
    T122085 [SBCOI2020]时光的流逝
    LC 918. Maximum Sum Circular Subarray
    1026 Table Tennis
    LC 1442. Count Triplets That Can Form Two Arrays of Equal XOR
    LC 1316. Distinct Echo Substrings
    LC 493. Reverse Pairs
    1029 Median (二分)
  • 原文地址:https://www.cnblogs.com/olinr/p/9574093.html
Copyright © 2011-2022 走看看