(WAWAWAWAWAWA) codevs 2421 序列操作

二次联通门 : codevs 2421 序列操作

/*

    已经...
    没有什么好怕的的了...

    16K的代码...

    调个MMP啊...

*/
#include <cstdio>

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < ‘0‘ || word > ‘9‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

inline int max (int a, int b)
{
    return a > b ? a : b;
}

inline int min (int a, int b)
{
    return a < b ? a : b;
}

inline int swap (int &a, int &b)
{
    register int now = a;
    a = b;
    b = now;
}

struct Segment_Tree_Data
{
    Segment_Tree_Data *Left, *Right;

    int Mid;
    int key;

    int l, r;

    int Nor_Flandre;
    bool Rev_Flandre;

    int Zero_Prefix_, Zero_Suffix_;
    int Zero_Series_Count;
    int Zero_Count;

    int One_Prefix_, One_Suffix_;
    int One_Series_Count;
    int One_Count;

    Segment_Tree_Data ()
    {
        Left = Right = NULL;
        Nor_Flandre = 0;
        Rev_Flandre = 0;
    }

    inline void Clear_One ()
    {
        One_Count = 0;
        One_Prefix_ = One_Suffix_ = 0;
        One_Series_Count = 0;
    }

    inline void Clear_Zero ()
    {
        Zero_Count = 0;
        Zero_Prefix_ = Zero_Suffix_ = 0;
        Zero_Series_Count = 0;
    }

    inline void Cover_One ()
    {
        One_Count = r - l + 1;
        One_Prefix_ = One_Count;
        One_Suffix_ = One_Count;
        One_Series_Count = One_Count;
    }

    inline void Cover_Zero ()
    {
        Zero_Count = r - l + 1;
        Zero_Prefix_ = Zero_Count;
        Zero_Suffix_ = Zero_Count;
        Zero_Series_Count = Zero_Count;
    }

    inline void Swap_Zero_and_One ()
    {
        swap (Zero_Count, One_Count);
        swap (Zero_Prefix_, One_Prefix_);
        swap (Zero_Suffix_, One_Suffix_);
        swap (Zero_Series_Count, One_Series_Count);
    }
};

Segment_Tree_Data *Root;

int Answer;

struct Answer_Type
{
    int size;
    int _Prefix, _Suffix;
    int Count;
    int Answer;
};

class Segment_Tree_Type
{
    private :

        inline void Up (Segment_Tree_Data *&now)
        {
            if (now->l == now->r)
                return ;/*
            now->Zero_Prefix_ = max (now->Left->Zero_Prefix_, now-

>Left->Zero_Count + now->Right->Zero_Prefix_);
            now->Zero_Suffix_ = max (now->Right->Zero_Suffix_, now-

>Right->Zero_Count + now->Left->Zero_Suffix_);
            now->Zero_Series_Count = max (max (now->Left-

>Zero_Series_Count, now->Right->Zero_Series_Count), now->Right-

>Zero_Prefix_ + now->Left->Zero_Suffix_);

            now->One_Prefix_ = max (now->Left->One_Prefix_, now->Left-

>One_Count + now->Right->One_Prefix_);
            now->One_Suffix_ = max (now->Right->One_Suffix_, now-

>Right->One_Count + now->Left->One_Suffix_);
            now->One_Series_Count = max (max (now->Left-

>One_Series_Count, now->Right->One_Series_Count), now->Right-

>One_Prefix_ + now->Left->One_Suffix_);
            */
            now->One_Prefix_ = now->Left->One_Count == now

->Left->r - now->Left->l + 1 ? now->Left->One_Count : now->Left-

>One_Prefix_;
            now->One_Suffix_ = now->Right->One_Count == 

now->Right->r - now->Right->l + 1 ? now->Right->One_Count : now->Right

->One_Suffix_;

            now->Zero_Prefix_ = now->Left->Zero_Count == 

now->Left->r - now->Left->l + 1 ? now->Left->Zero_Count : now->Left-

>Zero_Prefix_;
            now->Zero_Suffix_ = now->Right->Zero_Count == 

now->Right->r - now->Right->l + 1 ? now->Right->Zero_Count : now-

>Right->Zero_Suffix_;

            now->One_Series_Count = max (max (now->Left-

>One_Series_Count, now->Right->One_Series_Count), now->Left-

>One_Suffix_ + now->Right->One_Prefix_);
            now->Zero_Series_Count = max (max (now->Left-

>Zero_Series_Count, now->Right->Zero_Series_Count), now->Left-

>Zero_Suffix_ + now->Right->Zero_Prefix_);

            now->One_Count = now->Left->One_Count + now->Right-

>One_Count;
            now->Zero_Count = now->Left->Zero_Count + now->Right-

>Zero_Count;
            return ;
        }

        inline void Down (Segment_Tree_Data *&now)
        {
            if (now->l == now->r)
                return ;
            if (now->Nor_Flandre)
            {
                if (now->Nor_Flandre == 1)
                {/*
                    now->Left->One_Count = now->Left->r - now->Left->l 

+ 1;
                    now->Right->One_Count = now->Right->r - now->Right

->l + 1;

                    now->Left->One_Prefix_ = now->Left->One_Count;
                    now->Left->One_Suffix_ = now->Left->One_Count;
                    now->Right->One_Prefix_ = now->Right->One_Count;
                    now->Right->One_Suffix_ = now->Right->One_Count;

                    now->Left->One_Series_Count = now->Left->One_Count;
                    now->Right->One_Series_Count = now->Right-

>One_Count;

                    now->Left->Nor_Flandre = 1;
                    now->Right->Nor_Flandre = 1;
                    */
                    now->Left->Cover_One ();
                    now->Right->Cover_One ();
                    now->Left->Rev_Flandre = false;
                    now->Right->Rev_Flandre = false;
                    now->Left->Clear_Zero ();
                    now->Right->Clear_Zero ();

                    now->Nor_Flandre = 0;
                }
                else if (now->Nor_Flandre == 2)
                {/*
                    now->Left->Zero_Count = now->Left->r - now->Left->l 

+ 1;
                    now->Right->Zero_Count = now->Right->r - now-

>Right->l + 1;

                    now->Left->Zero_Prefix_ = now->Left->Zero_Count;
                    now->Left->Zero_Suffix_ = now->Left->Zero_Count;
                    now->Right->Zero_Prefix_ = now->Right->Zero_Count;
                    now->Right->Zero_Suffix_ = now->Right->Zero_Count;

                    now->Left->Zero_Series_Count = now->Left-

>Zero_Count;
                    now->Right->Zero_Series_Count = now->Right-

>Zero_Count;

                    now->Left->Nor_Flandre = 2;
                    now->Right->Nor_Flandre = 2;
                    */
                    now->Left->Cover_Zero ();
                    now->Right->Cover_Zero ();
                    now->Left->Rev_Flandre = false;
                    now->Right->Rev_Flandre = false;
                    now->Left->Clear_One ();
                    now->Right->Clear_One ();

                    now->Nor_Flandre = 0;
                }
            }
            if (now->Rev_Flandre)
            {/*
                swap (now->Left->One_Count, now->Left->Zero_Count);
                swap (now->Left->One_Prefix_, now->Left->Zero_Count);
                swap (now->Left->One_Series_Count, now->Left-

>Zero_Series_Count);
                swap (now->Left->One_Suffix_, now->Left->Zero_Suffix_);

                swap (now->Right->One_Count, now->Right->Zero_Count);
                swap (now->Right->One_Prefix_, now->Right->Zero_Count);
                swap (now->Right->One_Series_Count, now->Right-

>Zero_Series_Count);
                swap (now->Right->One_Suffix_, now->Left-

>Zero_Suffix_);
               */
                   now->Left->Swap_Zero_and_One ();
                now->Right->Swap_Zero_and_One ();
                now->Left->Rev_Flandre = true;
                now->Right->Rev_Flandre = true;

                now->Rev_Flandre = false;
            }
        }

    public :

        void Build (Segment_Tree_Data *&now, int l, int r)
        {
            now = new Segment_Tree_Data;
            now->l = l;
            now->r = r;
            if (l == r)
            {
                read (now->key);
                if (now->key)
                {
                    now->One_Count = 1;
                    now->One_Prefix_ = 1;
                    now->One_Suffix_ = 1;
                    now->One_Series_Count = 1;
                    now->Clear_Zero ();
                    return ;
                }
                else
                {
                    now->Zero_Count = 1;
                    now->Zero_Prefix_ = 1;
                    now->Zero_Suffix_ = 1;
                    now->Zero_Series_Count = 1;
                    now->Clear_One ();
                    return ;
                }
            }
            now->Mid = l + r >> 1;
            Build (now->Left, l, now->Mid);
            Build (now->Right, now->Mid + 1, r);
            Up (now);
        }

        void Change_First (Segment_Tree_Data *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
            {/*
                now->Zero_Count = now->r - now->l + 1;
                now->Zero_Prefix_ = now->Zero_Count;
                now->Zero_Suffix_ = now->Zero_Count;
                now->Zero_Series_Count = now->Zero_Count;
*/
                now->Cover_Zero ();
                now->Clear_One ();
                now->Nor_Flandre = 2;
                return ;
            }
            Down (now);
            if (l <= now->Mid)
                Change_First (now->Left, l, min (now->Mid, r));
            if (r > now->Mid)
                Change_First (now->Right, max (now->Mid + 1, l), r);
            Up (now);
        }

        void Change_Second (Segment_Tree_Data *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
            {
                now->Cover_One ();
                now->Clear_Zero ();

                now->Nor_Flandre = 1;
                return ;
            }
            Down (now);
            if (l <= now->Mid)
                Change_Second (now->Left, l, min (now->Mid, r));
            if (r > now->Mid)
                Change_Second (now->Right, max (now->Mid + 1, l), r);
            Up (now);
        }

        void Change_Third (Segment_Tree_Data *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
            {
                now->Swap_Zero_and_One ();
                now->Rev_Flandre = true;
                return ;
            }
            Down (now);
            if (l <= now->Mid)
                Change_Third (now->Left, l, min (now->Mid, r));
            if (r > now->Mid)
                Change_Third (now->Right, max (now->Mid + 1, l), r);
            Up (now);
        }

        int Query_First (Segment_Tree_Data *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
                return now->One_Count;
            Down (now);
            register int res = 0;
            if (l <= now->Mid)
                res += Query_First (now->Left, l, min (now->Mid, r));
            if (r > now->Mid)
                res += Query_First (now->Right, max (now->Mid + 1, l), 

r);
            Up (now);
            return res;
        }
        /*
        Segment_Tree_Data *Query_Second (Segment_Tree_Data *&now, int 

l, int r)
        {
            if (l <= now->l && now->r <= r)
                return now;
            Down (now);
            Up (now);
            Segment_Tree_Data *res = new Segment_Tree_Data;
            Segment_Tree_Data *now_1 = new Segment_Tree_Data, *now_2 = 

new Segment_Tree_Data;
            bool flag_1 = false, flag_2 = false;
            if (l <= now->Mid)
            {
                flag_1 = true;
                now_1 = Query_Second (now->Left, l, min (now->Mid, r));
            }
            if (r > now->Mid)
            {
                flag_2 = true;
                now_2 = Query_Second (now->Right, max (now->Mid + 1, 

l), r);
            }
            if (flag_1 && flag_2)
            {
                now_1 = Query_Second (now->Left, l, min (now->Mid, r));
                now_2 = Query_Second (now->Right, max (now->Mid + 1, 

l), r);
                res.One_Prefix_ = max (now_1.One_Prefix_, 

now_1.One_Count + now_2.One_Prefix_);
                res.One_Suffix_ = max (now_2.One_Suffix_, 

now_2.One_Count + now_1.One_Suffix_);
                res.One_Series_Count = max (max 

(now_1.One_Series_Count, now_2.One_Series_Count), now_1.One_Suffix_ + 

now_2.One_Prefix_);
                return res;

              now_1 = Query_Second (now->Left, l, min (now->Mid, r));
              now_2 = Query_Second (now->Right, max (now->Mid + 1, l), 

r);
                res->One_Count = now_1->One_Count + 

now_2->One_Count;
                res->One_Prefix_ = max (now_1->One_Prefix_, now_1-

>One_Count + now_2->One_Prefix_);
                res->One_Suffix_ = max (now_2->One_Suffix_, now_2-

>One_Count + now_1->One_Suffix_);
                res->One_Series_Count = max (max (now_1-

>One_Series_Count, now_2->One_Series_Count), now_1->One_Suffix_ + 

now_2->One_Prefix_);
                Answer = max (Answer, res->One_Series_Count);
                Answer = max (Answer, res->One_Prefix_);
                Answer = max (Answer, res->One_Suffix_);
                return res;
            }
            if (flag_1)
            {
                Answer = max (Answer, now_1->One_Series_Count);
                Answer = max (Answer, now_1->One_Prefix_);
                Answer = max (Answer, now_1->One_Suffix_);
                return now_1;
            }
            if (flag_2)
            {
                Answer = max (Answer, now_2-

>One_Series_Count);
                Answer = max (Answer, now_2-

>One_Prefix_);
                Answer = max (Answer, now_2-

>One_Suffix_);
                return now_2;
            }
        }*/

        Answer_Type Query_ (Segment_Tree_Data *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
                return (Answer_Type)
                {
                    now->r - now->l + 1,
                    now->One_Prefix_,
                    now->One_Suffix_,
                    now->One_Count,
                    now->One_Series_Count
                };
            Down (now);
            Up (now);
            Answer_Type now_1, now_2;
            register bool flag_1 = false, flag_2 = false;
            if (l <= now->Mid)
            {
                flag_1 = true;
                now_1 = Query_ (now->Left, l, min (now

->Mid, r));
            }
            if (r > now->Mid)
            {
                flag_2 = true;
                now_2 = Query_ (now->Right, max (now-

>Mid + 1, l), r);
            }
            if (flag_1 && flag_2)
            {
                Answer_Type res;
                res.Count = now_1.Count + now_2.Count;
                res._Prefix = now_1.size == now_1.Count 

? now_1.Count : now_1._Prefix;
                res._Suffix = now_2.size == now_2.Count 

? now_2.Count : now_2._Suffix;
                res.Answer = max (max (now_1.Answer, 

now_2.Answer), now_1._Suffix + now_2._Prefix);
                return res;
            }
            return flag_1 ? now_1 : now_2;
        }
};

Segment_Tree_Type Tree;
int N, M;

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    Root = NULL;
    Tree.Build (Root, 1, N);
    int type, x, y;
    for (; M--; )
    {
        read (type);
        read (x);
        x++;
        read (y);
        y++;
        if (type == 0)
            Tree.Change_First (Root, x, y);
        else if (type == 1)
            Tree.Change_Second (Root, x, y);
        else if (type == 2)
            Tree.Change_Third (Root, x, y);
        else if (type == 3)
           printf ("%d\n", Tree.Query_First (Root, x, y));
        else
        {
//            Answer = -1;
//            Tree.Query_Second (Root, x, y);
//            printf ("%d\n", Answer);
            Answer_Type res = Tree.Query_ (Root, x, y);
            printf ("%d\n", max (max (res._Prefix, 

res._Suffix), res.Answer));
        }
    }
    return 0;
}
时间: 2024-08-26 23:49:57

(WAWAWAWAWAWA) codevs 2421 序列操作的相关文章

序列操作

2421 序列操作 http://codevs.cn/problem/2421/ 2010年省队选拔赛四川  题目等级 : 大师 Master 题目描述 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3

bzoj 1858: [Scoi2010] 序列操作 题解

[原题] 1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1031  Solved: 529 [Submit][Status] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内

Python基础--通用序列操作

Python 继续 Python包含6种内建的序列,各自是:列表.元组.字符串.Unicode字符串.buffer对象和xrange对象.我们将逐步进行介绍. 今天主要介绍一下通用序列操作.放之四海而皆准. 1 索引 全部程序猿都知道,索引下标从零開始.Python也是这样, 索引0指向序列中第一个元素. 可是与C++相比.Python又添加了负索引.最后1个元素的索引是-1,从右至左是-2.-3 - 字符串字面值直接能够索引: >>>'Hello'[1] e 2 分片 分片通过冒号隔开

1858: [Scoi2010]序列操作

1858: [Scoi2010]序列操作 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一

[python基础(一)]序列操作基础

一.python的数据结构 容器:包含其他对象的任意对象. 包括:序列(例如列表,元组),映射(例如字典),集合等.主要是序列和映射. 二.序列操作 索引,分片,加,乘,检查某元素是否是该序列成员.此外,计算序列长度,寻找最大,最下元素. 1.索引 正数:从0开始,左至右: 负数:从-1开始,有至左 2.分片 两个索引作为边界,第一个索引元素包含在分片内,第二个不包含. A='123456789' Print A[2:5] '345' 3.序列相加 条件:序列的类型相同 4.乘法 5.成员资格

OpenCV视频序列操作基础

 从视频序列中抓取一帧 OpenCV支持从摄像头或视频文件(AVI)中抓取图像. 从摄像头获取初始化: CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0 从视频文件获取初始化: CvCapture* capture = cvCaptureFromAVI("infile.avi"); 抓取帧: IplImage* img = 0; if(!cvGrabFrame(capture)){  

【BZOJ-1858】序列操作 线段树

1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1961  Solved: 991[Submit][Status][Discuss] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区

【BZOJ 1858】 [Scoi2010]序列操作

1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1368 Solved: 712 [Submit][Status][Discuss] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区

bzoj 1858: [Scoi2010]序列操作

1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右中的1和0连续个数,并在op=4时特殊处理一下. Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全