• luogu P3797 妖梦斩木棒


     二次联通门 : luogu P3797 妖梦斩木棒

    /*
        luogu P3797 妖梦斩木棒
        
            建一棵线段树,维护
    
            1.有几段完整的木棍,
    
            2.左边是否有向右边的开口,
    
            3.右边是否有向左边的开口,
    
            4.以及是否完全无开口(全为'X')(便于区间合并)。
    */
    #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 ();
        }
    }
    
    int N, M;
    
    struct S_D
    {
        
        S_D *Left, *Right;
        
        bool key;
        bool Bracket_L, Bracket_R;
        
        int value;
        
        int l, r;
        int Mid;
        
        inline void F_Updata (bool now_1, bool now_2, bool now)
        {
            Bracket_L = now_1;
            Bracket_R = now_2;
            key = now;
            value = 0;
        }
        
        S_D (int __l, int __r) : l (__l), r (__r)
        {
            Left = Right = NULL;
            
            Mid = __l + __r >> 1;
            key = false;
            value = 0;
            Bracket_L = Bracket_R = false;
        }
        
        S_D ()
        {
            Left = Right = NULL;
            Bracket_L = Bracket_R = false;
            key = false;
            
            value = 0;
        }
        
        inline void Up ()
        {
            this->key = this->Left->key & this->Right->key;
            
            this->Bracket_L = this->Left->key ? this->Right->Bracket_L : this->Left->Bracket_L;
            this->Bracket_R = this->Right->key ? this->Left->Bracket_R : this->Right->Bracket_R;
            
            this->value = this->Left->value + this->Right->value;
                
            if (this->Left->Bracket_R && this->Right->Bracket_L && !this->Right->key && !this->Left->key)
                this->value ++;
            
        }
        
        inline void Clear ()
        {
            Left = Right = NULL;
            Bracket_L = Bracket_R = false;
            key = false;
            
            value = 0;
        }
    };
    
    S_D *Root;
    
    #define Max 1001
    
    class Segment_Tree_Type
    {    
        private :
            
            S_D *Pool[Max];
            
            int Count;
            
            S_D* __Query_ (S_D *&now, int l, int r)
            {
                if (l <= now->l && now->r <= r)
                    return now;
                    
                S_D *res = Pool[++ Count];
                
                if (l <= now->Mid)
                    res->Left = __Query_ (now->Left, l, r);
                if (r > now->Mid)
                    res->Right = __Query_ (now->Right, l, r);
                    
                if (res->Left && res->Right)
                {
                    res->F_Updata (false, false, false);
                    res->Up ();
                }
                else if (res->Left)
                    res = res->Left;
                else if (res->Right)
                    res = res->Right;
                else res = NULL;
                
                return res;
            }
            
        public :
            
            Segment_Tree_Type ()
            {
                for (int i = 0; i < Max; i ++)
                    Pool[i] = new S_D ();
                    
                Count = 0;
            }
            
            void Build (S_D *&now, int l, int r)
            {
                now = new S_D (l, r);
                if (l == r)
                {
                    if (l == 1)
                        now->F_Updata (false, true, false);
                    else if (l == N)
                        now->F_Updata (true, false, false);
                    else
                        now->F_Updata (true, true, true);
                    
                    return ;
                }
                Build (now->Left, l, now->Mid);
                Build (now->Right, now->Mid + 1, r);
                now->Up ();
            }
            
            void Change (S_D *&now, int pos, int to)
            {
                if (now->l == now->r)
                {
                    if (to == 0)
                        now->F_Updata (true, false, false);
                    else if (to == 1)
                        now->F_Updata (false, true, false);
                    else
                        now->F_Updata (true, true, true);
                    
                    return ;
                }
                if (pos <= now->Mid)
                    Change (now->Left, pos, to);
                if (pos > now->Mid)
                    Change (now->Right, pos, to);
                now->Up (); 
            }
        
            int Query (int x, int y)
            {
                register int now = __Query_ (Root, x, y)->value;
                
                for (int i = 1; i <= Count; i ++)
                    Pool[i]->Clear ();
                    
                Count = 0;
                return now;
            }
    };
    
    Segment_Tree_Type Tree;
    
    int main (int argc, char *argv[])
    {
        read (N);
        read (M);
        
        Tree.Build (Root, 1, N);     
        char type[3];
        for (int x, y; M --; )
        {
            read (x);
            read (y);
            if (x == 1)
            {
                scanf ("%s", type);
                if (type[0] == 'X')
                    Tree.Change (Root, y, 2);
                else if (type[0] == '(')
                    Tree.Change (Root, y, 1);
                else
                    Tree.Change (Root, y, 0);
            }
            else
            {
                read (x);
                printf ("%d
    ", Tree.Query (y, x));
            }
        }
        return 0;
    }
  • 相关阅读:
    20145212 《Java程序设计》第10周学习总结
    20145212 实验五《Java网络编程》
    20145212 《Java程序设计》第9周学习总结
    20145212 实验四《Andoid开发基础》
    《信息安全系统设计基础》第2周总结
    20145210《信息安全系统设计基础》第1周学习总结
    20145210 《信息安全系统设计基础》第0周学习总结
    20145210姚思羽_课程总结
    20145210实验五《Java网络编程》
    20145210 《Java程序设计》第十周学习总结
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7045527.html
Copyright © 2020-2023  润新知