• [SCOI 2010] 序列操作


    [题目链接]

           https://www.lydsy.com/JudgeOnline/problem.php?id=1858

    [算法]

            用线段树维护 :

            1. 区间中1的个数

            2. 左端点向右延伸最长连续1的长度

            3. 右端点向左延伸最长连续1的长度

            4. 左端点向右延伸最长连续0的长度

            5. 右端点向左延伸最长连续0的长度

            6. 区间中最多有多少个连续的1

            细节较为繁琐 , 写代码时要严谨

            时间复杂度 : O(NlogN)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100010
    typedef long long ll;
    typedef long double ld;
    
    int n , q;
    int a[MAXN];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    struct Segment_Tree
    {
        struct Node
        {
            int l , r;
            int lm0 , rm0 , lm1 , rm1 , value0 , value1 , cnt;
            int taga , tagb;    
        } Tree[MAXN << 2];
        inline void update(int index)
        {
            int l = Tree[index].l , r = Tree[index].r;
            int mid = (l + r) >> 1;
            Tree[index].cnt = Tree[index << 1].cnt + Tree[index << 1 | 1].cnt;
            if (Tree[index << 1].cnt == mid - l + 1) Tree[index].lm1 = mid - l + 1 + Tree[index << 1 | 1].lm1;
            else Tree[index].lm1 = Tree[index << 1].lm1;
            if (Tree[index << 1 | 1].cnt == r - mid) Tree[index].rm1 = r - mid + Tree[index << 1].rm1;
            else Tree[index].rm1 = Tree[index << 1 | 1].rm1;
            if (Tree[index << 1].cnt == 0) Tree[index].lm0 = mid - l + 1 + Tree[index << 1 | 1].lm0;
            else Tree[index].lm0 = Tree[index << 1].lm0;
            if (Tree[index << 1 | 1].cnt == 0) Tree[index].rm0 = r - mid + Tree[index << 1].rm0;
            else Tree[index].rm0 = Tree[index << 1 | 1].rm0;
            Tree[index].value0 = max(Tree[index << 1].value0 , Tree[index << 1 | 1].value0);
            chkmax(Tree[index].value0 , Tree[index << 1].rm0 + Tree[index << 1 | 1].lm0);
            Tree[index].value1 = max(Tree[index << 1].value1 , Tree[index << 1 | 1].value1);
            chkmax(Tree[index].value1 , Tree[index << 1].rm1 + Tree[index << 1 | 1].lm1);
        }
        inline void pushdown(int index)
        {
            int l = Tree[index].l , r = Tree[index].r;
            int mid = (l + r) >> 1;
            if (Tree[index].taga == 0)
            {
                Tree[index << 1].cnt = Tree[index << 1 | 1].cnt = 0;
                Tree[index << 1].lm1 = Tree[index << 1 | 1].lm1 = 0;
                Tree[index << 1].rm1 = Tree[index << 1 | 1].rm1 = 0;
                Tree[index << 1].lm0 = Tree[index << 1].rm0 =  mid - l + 1;
                Tree[index << 1 | 1].lm0 = Tree[index << 1 | 1].rm0 = r - mid;
                Tree[index << 1].value0 = mid - l + 1;
                Tree[index << 1 | 1].value0 = r - mid;
                Tree[index << 1].value1 = Tree[index << 1 | 1].value1 = 0;
                Tree[index << 1].taga = Tree[index << 1 | 1].taga = 0;
                Tree[index << 1].tagb = Tree[index << 1 | 1].tagb = 0;
                Tree[index].taga = -1;
            } else if (Tree[index].taga == 1)
            {
                Tree[index << 1].cnt = mid - l + 1;
                Tree[index << 1 | 1].cnt = r - mid;
                Tree[index << 1].lm1 = Tree[index << 1].rm1 = mid - l + 1;
                Tree[index << 1].lm0 = Tree[index << 1].rm0 = 0;
                Tree[index << 1 | 1].lm0 = Tree[index << 1 | 1].rm0 = 0;
                Tree[index << 1 | 1].lm1 = Tree[index << 1 | 1].rm1 = r - mid;
                Tree[index << 1].value0 = Tree[index << 1 | 1].value0 = 0;
                Tree[index << 1].value1 = mid - l + 1;
                Tree[index << 1 | 1].value1 = r - mid;
                Tree[index << 1].taga = Tree[index << 1 | 1].taga = 1;
                Tree[index << 1].tagb = Tree[index << 1 | 1].tagb = 0;
                Tree[index].taga = -1;
            }
            if (Tree[index].tagb)
            {
                Tree[index << 1].cnt = (mid - l + 1) - Tree[index << 1].cnt;
                Tree[index << 1 | 1].cnt = (r - mid) - Tree[index << 1 | 1].cnt;
                swap(Tree[index << 1].value0 , Tree[index << 1].value1);
                swap(Tree[index << 1 | 1].value0 , Tree[index << 1 | 1].value1);
                swap(Tree[index << 1].lm0 , Tree[index << 1].lm1);
                swap(Tree[index << 1].rm0 , Tree[index << 1].rm1);
                swap(Tree[index << 1 | 1].lm0 , Tree[index << 1 | 1].lm1);
                swap(Tree[index << 1 | 1].rm0 , Tree[index << 1 | 1].rm1);
                Tree[index << 1].tagb ^= 1;
                Tree[index << 1 | 1].tagb ^= 1;
                Tree[index].tagb = 0;
            } 
        }
        inline void build(int index , int l , int r)
        {
            Tree[index].l = l; Tree[index].r = r;
            Tree[index].taga = -1;
            Tree[index].tagb = 0;
            if (l == r)
            {
                if (a[l] == 0)
                {
                    Tree[index].lm0 = Tree[index].rm0 = 1;    
                    Tree[index].value0 = 1;
                } else
                {
                    Tree[index].lm1 = Tree[index].rm1 = 1;
                    Tree[index].value1 = 1;
                    Tree[index].cnt = 1;
                }
                return;
            }
            int mid = (l + r) >> 1;
            build(index << 1 , l , mid);
            build(index << 1 | 1 , mid + 1 , r);
            update(index);
        }
        inline void modify(int index , int l , int r , int value)
        {
            if (Tree[index].l == l && Tree[index].r == r)
            {
                if (value == 0)
                {
                        Tree[index].lm1 = Tree[index].rm1 = 0;
                    Tree[index].lm0 = Tree[index].rm0 = r - l + 1;
                    Tree[index].cnt = 0;
                    Tree[index].value0 = r - l + 1;
                    Tree[index].value1 = 0;
                    Tree[index].taga = value;
                    Tree[index].tagb = 0;
                } else
                {
                        Tree[index].lm0 = Tree[index].rm0 = 0;
                    Tree[index].lm1 = Tree[index].rm1 = r - l + 1;
                    Tree[index].cnt = r - l + 1;
                    Tree[index].value0 = 0;
                    Tree[index].value1 = r - l + 1;
                    Tree[index].taga = value;
                    Tree[index].tagb = 0;
                }
                return;
            }
            pushdown(index);
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= r) modify(index << 1 , l , r , value);
            else if (mid + 1 <= l) modify(index << 1 | 1 , l , r , value);
            else
            {
                modify(index << 1 , l , mid , value);
                modify(index << 1 | 1 , mid + 1 , r , value);
            }
            update(index);
        }
        inline void reverse(int index , int l , int r)
        {
            if (Tree[index].l == l && Tree[index].r == r)
            {
                Tree[index].cnt = (r - l + 1) - Tree[index].cnt;
                            swap(Tree[index].lm0 , Tree[index].lm1);
                            swap(Tree[index].rm0 , Tree[index].rm1);
                            swap(Tree[index].value0 , Tree[index].value1);
                Tree[index].tagb ^= 1;
                return;
            }
            pushdown(index);
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= r) reverse(index << 1 , l , r);
            else if (mid + 1 <= l) reverse(index << 1 | 1 , l , r);
            else
            {
                reverse(index << 1 , l , mid);
                reverse(index << 1 | 1 , mid + 1 , r);
            }
            update(index);
        }
        inline int queryA(int index , int l , int r)
        {
            if (Tree[index].l == l && Tree[index].r == r)
                return Tree[index].cnt;
            pushdown(index);
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= r) return queryA(index << 1 , l , r);
            else if (mid + 1 <= l) return queryA(index << 1 | 1 , l , r);
            else return queryA(index << 1 , l , mid) + queryA(index << 1 | 1 , mid + 1 , r);
        }
        inline int queryB(int index , int l , int r)
        {
            if (Tree[index].l == l && Tree[index].r == r)
                return Tree[index].value1;
            pushdown(index);
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= r) return queryB(index << 1 , l , r);
            else if (mid + 1 <= l) return queryB(index << 1 | 1 , l , r);
            else 
            {
                int ret = max(queryB(index << 1 , l , mid) , queryB(index << 1 | 1 , mid + 1 , r));
                chkmax(ret , min(mid - l + 1 , Tree[index << 1].rm1) + min(r - mid , Tree[index << 1 | 1].lm1));
                return ret;
            }
        }
    } SGT;
    
    int main()
    {
        
        read(n); read(q);
        for (int i = 1; i <= n; i++) read(a[i]);
        SGT.build(1 , 1 , n);
        while (q--)
        {
            int type;
            read(type);
            if (type == 0)
            {
                int l , r;
                read(l); read(r);
                ++l; ++r;
                SGT.modify(1 , l , r , 0);    
            } else if (type == 1)
            {
                int l , r;
                read(l); read(r);
                ++l; ++r;
                SGT.modify(1 , l , r , 1);
            } else if (type == 2)
            {
                int l , r;
                read(l); read(r);
                ++l; ++r;
                SGT.reverse(1 , l , r);
            } else if (type == 3)
            {
                int l , r;
                read(l); read(r);
                ++l; ++r;
                printf("%d
    " , SGT.queryA(1 , l , r));
            } else
            {
                int l , r;
                read(l); read(r);
                ++l; ++r;
                printf("%d
    " , SGT.queryB(1 , l , r));
            }
        }
        
        return 0;
    }
  • 相关阅读:
    #Leetcode# 876. Middle of the Linked List
    #Leetcode# 237. Delete Node in a Linked List
    #Leetcode# 234. Palindrome Linked List
    #Leetcode# 149. Max Points on a Line
    #Leetcode# 152. Maximum Product Subarray
    #Leetcode# 228. Summary Ranges
    #Leetcode# 227. Basic Calculator II
    PAT 1089 狼人杀-简单版
    linux——web安全之sql注入【预习阶段】
    linux——攻防技术介绍|主动攻击|被动攻击
  • 原文地址:https://www.cnblogs.com/evenbao/p/10051044.html
Copyright © 2020-2023  润新知