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

    题目背景

    话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来。

    Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢哗者,遂与外人间隔。”

    题目描述

    设想一下,腰鼓有两面,一面是红色的,一面是白色的。初二的苏大学神想给你这个oier出一道题。假设一共有N(1<=N<=20,000)个同学表演,表演刚开始每一个鼓都是红色面朝向观众,舞蹈老师会发出M(1<=M<=20,000)个指令,如果指令发给第i个表演的同学,这位同学就会把腰鼓反过来,如果腰鼓之前是红色面朝向观众的,那么就会变成白色面朝向观众,反之亦然。那么问题来了(!?),在老师每一次发出指令后,找到最长的连续的一排同学,满足每相邻的两个手中的腰鼓朝向观众的一面互不相同,输出这样一排连续的同学的人数。

    输入输出格式

    输入格式:

    第一行有两个整数, 分别为表演的同学总数N, 和指令总数M。

    之后M行, 每行有一个整数i: 1<=i<=N, 表示舞蹈老师发出的指令。

    输出格式:

    输出有M行, 其中每i行有一个整数.

    表示老师的第i条指令发出之后, 可以找到的满足要求的最长连续的一排表演同学有多长?

    输入输出样例

    输入样例#1: 
    6 2
    2
    4
    输出样例#1: 
    3
    5

    说明

    Huangc温馨提示:其实数据根本没你想象的那么大。。。[坏笑]、、

    Solution:

      本题线段树常规经典题。。。(话说洛谷标签有毒~本题怎么可能是道黄题嘛`!~)

      维护以下信息:区间左、右端点,从左端点开始的最大长度,从中间某点到右端点结束的最大长度,整个区间的满足条件的最大长度。

      每次更新时,从左右儿子转移,记得考虑一下左右儿子区间并起来的情况,瞎搞一下就$OK$了。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define Max(a,b) ((a)>(b)?(a):(b))
    using namespace std;
    const int N=100005;
    int n,m,lsu[N],rsu[N],lc[N],rc[N],asu[N];
    il int gi(){
        int a=0;char x=getchar();
        while(x<'0'||x>'9')x=getchar();
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return a;
    }
    il void pushup(int rt,int len){
        lsu[rt]=lsu[rt<<1],rsu[rt]=rsu[rt<<1|1];
        lc[rt]=lc[rt<<1],rc[rt]=rc[rt<<1|1];
        asu[rt]=Max(Max(lsu[rt<<1],Max(rsu[rt<<1|1],Max(rsu[rt<<1],lsu[rt<<1|1]))),Max(asu[rt<<1],asu[rt<<1|1]));
        if(rc[rt<<1]!=lc[rt<<1|1]){
            asu[rt]=Max(asu[rt],rsu[rt<<1]+lsu[rt<<1|1]);
            if(lsu[rt<<1]==(len-(len>>1)))lsu[rt]+=lsu[rt<<1|1];
            if(rsu[rt<<1|1]==(len>>1))rsu[rt]+=rsu[rt<<1];
        }
    }
    il void build(int l,int r,int rt){
        if(l==r){lsu[rt]=rsu[rt]=asu[rt]=1;return;}
        int m=l+r>>1;
        build(lson);build(rson);
        pushup(rt,r-l+1);
    }
    il void update(int x,int l,int r,int rt){
        if(l==r){lc[rt]^=1;rc[rt]^=1;return;}
        int m=l+r>>1;
        if(x<=m)update(x,lson);
        else update(x,rson);
        pushup(rt,r-l+1);
    }
    int main(){
        n=gi(),m=gi();
        int x;
        build(1,n,1);
        while(m--){
            x=gi();update(x,1,n,1);
            printf("%d
    ",asu[1]);
        }
        return 0;
    }
  • 相关阅读:
    C++中左移<<的使用
    学会构造素数序列
    有关lower_bound()函数的使用
    Codeforces Round #166 (Div. 2)
    暴力swap导致TLE问题解决办法
    memset的正确使用
    Codeforces Round #297 (Div. 2)
    Codeforces Round #170 (Div. 2)B
    Codeforces Round #176 (Div. 2)
    C/C++ sort函数的用法
  • 原文地址:https://www.cnblogs.com/five20/p/9066938.html
Copyright © 2011-2022 走看看