• [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
    ",T.query(l + 1,r + 1));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    远程视频监控之应用篇(mjpg-streamer)
    C语言存储类型
    基于Qt的wifi智能小车的制作(一)
    libevent和基于libevent的网络编程
    fdisk 分区格式化为ext4格式分区
    Makefile 中:= ?= += =的区别
    【计算机网络】详解网络层(二)ARP和RARP
    Nginx 反向代理 负载均衡 虚拟主机配置
    C# 对文本文件的几种读写方法总结
    Visual Studio中Image Watch的使用
  • 原文地址:https://www.cnblogs.com/evenbao/p/9709502.html
Copyright © 2020-2023  润新知