P2253 好一个一中腰鼓!

Posted olinr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 love_nmr 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(\n);
    }
    olinr ~~(0^_^0)+love_nmr;
}

 

以上是关于P2253 好一个一中腰鼓!的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P2253 好一个一中腰鼓 --线段树

P2253 好一个一中腰鼓!

洛谷 P2253 好一个一中腰鼓!

洛谷P2253 好一个一中腰鼓!

线段树 P2253 好一个一中腰鼓!

P2253 好一个一中腰鼓!