• [BZOJ 3196] 二逼平衡树


    [题目链接]

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

    [算法]

            树套树即可

            笔者的这份代码使用的是线段树套伸展树

            时间复杂度 : O(NlogN ^ 3)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 50010
    #define MAXP 2000005
    #define rint register int
    #pragma GCC optimize(2)
    const int inf = 2147483647;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    int n , m , rt = 0 , tot = 0 , sz = 0;
    int val[MAXN];
    
    struct Snode
    {
            int father , son[2];
            int value , cnt , sz;
    } a[MAXP];
    struct Splay
    {
            int rt[MAXP];
            stack< int > S;
            inline int get(int x)
            {
                    return a[a[x].father].son[1] == x;
            }
            inline void update(int x)
            {
                    a[x].sz = a[x].cnt;
                    if (a[x].son[0]) a[x].sz += a[a[x].son[0]].sz;
                    if (a[x].son[1]) a[x].sz += a[a[x].son[1]].sz;
            }
            inline void rotate(int x)
            {
                    int f = a[x].father , g = a[f].father;
                    int tmpx = get(x) , tmpf = get(f);
                    int w = a[x].son[tmpx ^ 1];
                    if (!f) return;
                    if (g) a[g].son[tmpf] = x;
                    a[x].son[tmpx ^ 1] = f;
                    a[f].son[tmpx] = w;
                    if (w) a[w].father = f;
                    a[f].father = x;
                    a[x].father = g;
                    update(f);
            }
            inline void splay(int k , int x)
            {
                    for (int f = a[x].father; (f = a[x].father); rotate(x))
                            rotate(get(f) == get(x) ? f : x);
                    rt[k] = x;
            }    
            inline int find(int root , int x)
            {
                    int now = rt[root];
                    while (now > 0)
                    {
                            if (a[now].value == x)
                            {
                                    splay(root , now);
                                    return now;
                            }
                            int tmp = a[now].value < x;
                            if (a[now].son[tmp]) now = a[now].son[tmp];
                            else return 0;
                    }
                    return 0;
            }
            inline int _insert(int root , int x)
            {
                    if (!rt[root])
                    {
                            int index = 0;
                            if (!S.empty())
                            {
                                index = S.top();
                                S.pop();
                            } else index = ++sz;
                            a[index].cnt = a[index].sz = 1;
                            a[index].value = x;
                            a[index].son[0] = a[index].son[1] = 0;
                            a[index].father = 0;
                            rt[root] = index;
                            return index; 
                    }
                    int now = rt[root];
                    while (now > 0)
                    {
                            if (a[now].value == x)
                            {
                                    ++a[now].cnt;
                                    splay(root , now);
                                    return now;
                            }
                            int tmp = a[now].value < x;
                            if (a[now].son[tmp]) now = a[now].son[tmp];
                            else
                            {
                                    int index = 0;
                                    if (!S.empty())
                                    {
                                        index = S.top();
                                        S.pop();
                                    } else index = ++sz;                     
                                    a[now].son[tmp] = index;
                                    a[index].father = now;
                                    a[index].value = x;
                                    a[index].sz = a[index].cnt = 1;
                                    a[index].son[0] = a[index].son[1] = 0;
                                    splay(root , index);
                                    return index;
                            }
                    }
                    return -1;
            }
            inline void join(int root , int u , int v)
            {
                    int now = u;
                    while (a[now].son[1]) now = a[now].son[1];
                    splay(root , now);
                    a[now].son[1] = v;
                    a[v].father = now;
            }
            inline void erase(int root , int x)
            {
                    int id = find(root , x);
                    if (!id) return;
                    splay(root , id);
                    --a[id].cnt;
                    if (a[id].cnt > 0) return;
                    S.push(id);
                    if (!a[id].son[0] && !a[id].son[1])
                    {
                            rt[root] = 0;
                            return;
                    }
                    if (!a[id].son[0])
                    {
                            rt[root] = a[id].son[1];
                            a[rt[root]].father = 0;
                            return;
                    }
                    if (!a[id].son[1])
                    {
                            rt[root] = a[id].son[0];
                            a[rt[root]].father = 0;
                            return;
                    }
                    join(root , a[id].son[0] , a[id].son[1]);
            }
            inline int query_pre(int root , int x)
            {
                    int id = find(root , x);
                    bool flg = false;
                    if (!id) 
                    {
                            id = _insert(root , x);
                            flg = true;
                    }
                    splay(root , id);
                    int ret;
                    if (!a[id].son[0])
                    {
                        ret = -inf;
                    } else
                    {
                        id = a[id].son[0];
                        while (a[id].son[1]) id = a[id].son[1];
                        ret = a[id].value;
                    }
                    if (flg) erase(root , x);
                    return ret;
            }
            inline int query_suc(int root , int x)
            {
                    int id = find(root , x);
                    bool flg = false;
                    if (!id) 
                    {
                            id = _insert(root , x);
                            flg = true;
                    }
                    splay(root , id);
                    int ret;
                    if (!a[id].son[1])
                    {
                        ret = inf;
                    } else
                    {    
                        id = a[id].son[1];
                           while (a[id].son[0]) id = a[id].son[0];
                           ret = a[id].value;
                       }
                    if (flg) erase(root , x);
                    return ret;
            }
            inline int query_s(int root , int x)
            {
                    int id = find(root , x);
                    bool flg = false;
                    if (!id) 
                    {
                            id = _insert(root , x);
                            flg = true;
                    }
                    splay(root , id);
                    int ret = a[a[id].son[0]].sz;
                    if (flg) erase(root , x);
                    return ret;
            }
    } T;
    struct Segment_Tree
    {
            int ls[MAXN << 2] , rs[MAXN << 2];
            Segment_Tree()
            {
                    memset(ls , 0 , sizeof(ls));
                    memset(rs , 0 , sizeof(rs));
            }
            inline void insert(int &k , int l , int r , int pos , int value)
            {
                    if (!k) k = ++tot;
                    T._insert(k , value);
                    if (l == r) return;
                    int mid = (l + r) >> 1;
                    if (mid >= pos) insert(ls[k] , l , mid , pos , value);
                    else insert(rs[k] , mid + 1 , r , pos , value);    
            }        
            inline int query_s(int k , int l , int r , int ql , int qr , int value)
            {
                    if (l == ql && r == qr)
                            return T.query_s(k , value);
                    int mid = (l + r) >> 1;
                    if (mid >= qr) return query_s(ls[k] , l , mid , ql , qr , value);
                    else if (mid + 1 <= ql) return query_s(rs[k] , mid + 1 , r , ql , qr , value);
                    else return query_s(ls[k] , l , mid , ql , mid , value) + query_s(rs[k] , mid + 1 , r , mid + 1 , qr , value);
            }
            inline void modify(int k , int l , int r , int pos , pair<int , int> val)
            {
                    T.erase(k , val.first);
                    T._insert(k , val.second);
                    if (l == r) return;
                    int mid = (l + r) >> 1;
                    if (mid >= pos) modify(ls[k] , l , mid , pos , val);
                    else modify(rs[k] , mid + 1  , r , pos , val);
            }
            inline int query_pre(int k , int l , int r , int ql , int qr , int value)
            {
                    if (l == ql && r == qr)
                            return T.query_pre(k , value);
                    int mid = (l + r) >> 1;
                    if (mid >= qr) return query_pre(ls[k] , l , mid , ql , qr , value);
                    else if (mid + 1 <= ql) return query_pre(rs[k] , mid + 1 , r , ql , qr , value);
                    else return max(query_pre(ls[k] , l , mid , ql , mid , value) , query_pre(rs[k] , mid + 1 , r , mid + 1 , qr , value));        
            } 
            inline int query_suc(int k , int l , int r , int ql , int qr , int value)
            {    
                    if (l == ql && r == qr)
                            return T.query_suc(k , value);
                    int mid = (l + r) >> 1;
                    if (mid >= qr) return query_suc(ls[k] , l , mid , ql , qr , value);
                    else if (mid + 1 <= ql) return query_suc(rs[k] , mid + 1 , r , ql , qr , value);
                    else return min(query_suc(ls[k] , l , mid , ql , mid , value) , query_suc(rs[k] , mid + 1 , r , mid + 1 , qr , value));
            }
    } SGT;
    
    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;
    }
    
    int main()
    {
            
    
            read(n); read(m);
            for (rint i = 1; i <= n; i++) read(val[i]);
            for (rint i = 1; i <= n; i++) SGT.insert(rt , 1 , n , i , val[i]);
            for (rint i = 1; i <= m; i++)
            {
                    int type;
                    read(type);
                    if (type == 1)
                    {
                            int l , r , k;
                            read(l); read(r); read(k);
                            printf("%d
    " , SGT.query_s(rt , 1 , n , l , r , k) + 1);
                    } 
                    if (type == 2)
                    {
                            int l , r , k;
                            read(l); read(r); read(k);
                            int lft = 0 , rgt = (int)1e8 , ans = 0;
                            while (lft <= rgt)
                            {
                                    int mid = (lft + rgt) >> 1;
                                    if (SGT.query_s(rt , 1 , n , l , r , mid) + 1 <= k)
                                    {
                                            ans = mid;
                                            lft = mid + 1;
                                    } else rgt = mid - 1;
                            }
                            printf("%d
    " , ans);
                    }
                    if (type == 3)
                    {
                            int pos , k;
                            read(pos); read(k);
                            SGT.modify(rt , 1 , n , pos , make_pair(val[pos] , k));
                            val[pos] = k;
                    }
                    if (type == 4)
                    {
                            int l , r , k;
                            read(l); read(r); read(k);
                            printf("%d
    " , SGT.query_pre(rt , 1 , n , l , r , k));
                    } 
                    if (type == 5)
                    {
                            int l , r , k;
                            read(l); read(r); read(k);
                            printf("%d
    " , SGT.query_suc(rt , 1 , n , l , r , k));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    HDC,CDC,CWindowDC,CClientDC,CPaintDC基础 笑风生 博客频道 CSDN.NET
    用web用户控件的方式添加到webpart,使用ajax实现无刷新总结
    .net 中利用owc 画制图表
    未安装在此服务器场中,无法添加到该范围
    敏捷软件开发宣言及原则
    调试 Windows SharePoint Services Workflow
    系统提示"System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本"解决办法
    安装及删除网站模板
    无法安装功能“265e193c6477431e8d3c98f51e6d3247”,因为加载事件接收器程序集“Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=a5e1d8429183b844”
    表单加载出错
  • 原文地址:https://www.cnblogs.com/evenbao/p/10187697.html
Copyright © 2020-2023  润新知