[BZOJ 1251] 序列终结者

[题目链接]

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

[算法]

        伸展树

        时间复杂度 : O(MlogN)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 50010
#define LRSON Tree[Tree[root].son[1]].son[0]

const int INF = 2e9;

int n , m;

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 Splay
{
        int root , total;
        struct Node
        {
                int fa , son[2];
                int sz , mx , tag , val;
                bool rev;
        } Tree[MAXN << 1];
        inline void init()
        {
                root = total = 0;
                for (int i = 0; i < MAXN; i++)
                {
                        Tree[i].fa = Tree[i].son[0] = Tree[i].son[1] = 0;
                        Tree[i].sz = Tree[i].val = Tree[i].tag = 0;
                        Tree[i].mx = -INF;
                        Tree[i].rev = false;
                }
        }
        inline void push_back(int x)
        {
                if (!root)
                {
                        root = ++total;
                        Tree[root].sz = 1;
                        Tree[root].mx = Tree[root].val = x;
                        return;
                }
                int now = root;
                while (Tree[now].son[1]) now = Tree[now].son[1];
                Tree[now].son[1] = ++total;
                Tree[total].fa = now;
                Tree[total].sz = 1;
                Tree[total].mx = Tree[total].val = x;
                splay(total,0);
        }
        inline void update(int x)
        {
                Tree[x].sz = Tree[Tree[x].son[0]].sz + Tree[Tree[x].son[1]].sz + 1;
                Tree[x].mx = Tree[x].val;
                if (Tree[x].son[0]) Tree[x].mx = max(Tree[x].mx,Tree[Tree[x].son[0]].mx);
                if (Tree[x].son[1]) Tree[x].mx = max(Tree[x].mx,Tree[Tree[x].son[1]].mx);
        }
        inline void pushdown(int x)
        {
                if (Tree[x].rev)
                {
                        swap(Tree[x].son[0],Tree[x].son[1]);
                        Tree[Tree[x].son[0]].rev ^= true;
                        Tree[Tree[x].son[1]].rev ^= true;
                        Tree[x].rev = false;
                }
                if (Tree[x].tag)
                {
                        Tree[Tree[x].son[0]].tag += Tree[x].tag;
                        Tree[Tree[x].son[1]].tag += Tree[x].tag;
                        Tree[Tree[x].son[0]].val += Tree[x].tag;
                        Tree[Tree[x].son[1]].val += Tree[x].tag;
                        Tree[Tree[x].son[0]].mx += Tree[x].tag;
                        Tree[Tree[x].son[1]].mx += Tree[x].tag;
                        Tree[x].tag = 0; 
                }
        }
        inline void rotate(int x)
        {
                int f = Tree[x].fa , g = Tree[f].fa;
                int tmpx = get(x) , tmpf = get(f);
                pushdown(f);
                pushdown(x);
                if (!f) return;
                Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1];
                if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].fa = f;
                Tree[x].son[tmpx ^ 1] = f;
                Tree[f].fa = x;
                Tree[x].fa = g;
                if (g) Tree[g].son[tmpf] = x;
                update(f);
                update(x);        
        }
        inline bool get(int x)
        {
                return Tree[Tree[x].fa].son[1] == x;
        }
        inline void splay(int x,int pos)
        {
                for (int f = Tree[x].fa; (f = Tree[x].fa) != pos; rotate(x))
                {
                        if (Tree[f].fa != pos)
                                rotate(get(f) == get(x) ? f : x);
                }
                if (!pos) root = x;        
        }
        inline int find(int k)
        {
                int now = root;
                while (now > 0)
                {
                        pushdown(now);
                        if (k <= Tree[Tree[now].son[0]].sz) now = Tree[now].son[0];
                        else
                        {
                                int size = Tree[Tree[now].son[0]].sz + 1;
                                if (k == size) return now;
                                k -= size;
                                now = Tree[now].son[1];
                        }
                }
        }
        inline void add(int l,int r,int value)
        {
                int pl = find(l - 1) , pr = find(r + 1);
                splay(pl,0); 
                splay(pr,root);
                Tree[LRSON].tag += value;
                Tree[LRSON].mx += value;
                Tree[LRSON].val += value;
                update(Tree[root].son[1]);
                update(root);
        }
        inline void reverse(int l,int r)
        {
                int pl = find(l - 1) , pr = find(r + 1);
                splay(pl,0);
                splay(pr,root);
                Tree[LRSON].rev ^= true;
        }
        inline int query(int l,int r)
        {
                int pl = find(l - 1) , pr = find(r + 1);
                splay(pl,0);
                splay(pr,root);
                return Tree[LRSON].mx;
        }
} T;

int main()
{
        
        read(n); read(m);
        T.init();
        T.push_back(-INF);
        for (int i = 1; i <= n; i++) T.push_back(0);
        T.push_back(-INF);
        while (m--)
        {
                int op;
                read(op);
                if (op == 1)
                {
                        int l , r , value;
                        read(l); read(r); read(value);
                        T.add(l + 1,r + 1,value);
                }        
                if (op == 2)
                {
                        int l , r;
                        read(l); read(r);
                        T.reverse(l + 1,r + 1);
                } 
                if (op == 3)
                {
                        int l , r;
                        read(l); read(r);
                        printf("%d\n",T.query(l + 1,r + 1));
                }
        }
        
        return 0;
    
}

 

posted @ 2018-09-26 20:33  evenbao  阅读(141)  评论(0编辑  收藏  举报