zoukankan      html  css  js  c++  java
  • [NOI2005]维护数列_Splay

    真的毫无算法可言,就是比谁的码力强罢了... 


    Code:

    #include<stack>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 500000 + 200;
    const int inf  = -1223;
    int ch[maxn][2], f[maxn], numv[maxn], maxv[maxn], lmax[maxn], rmax[maxn], sumv[maxn], tag[maxn], lazy[maxn],siz[maxn];
    int  root,  arr[maxn]; 
    stack <int> S;
    struct Operation
    {
        inline void init(){ for(int i = maxn - 10; i >= 1; --i) S.push(i); }
        inline int new_node(){ int u = S.top(); S.pop(); return u; }
        inline void erase(int x)
        { 
            ch[x][0] = ch[x][1] = f[x] = 0; 
            maxv[x] = numv[x] = lmax[x] = rmax[x] = sumv[x] = tag[x] = siz[x] = 0;
            lazy[x] = inf;
        }
        inline void trash(int u)
        {
            if(!u) return ;
            S.push(u);
            trash(ch[u][0]); 
            trash(ch[u][1]);
            erase(u);
        }
        inline void pushup(int o)
        {
            int ls = ch[o][0], rs = ch[o][1];
            maxv[o] = numv[o];
            sumv[o] = sumv[ls] + sumv[rs] + numv[o];
            siz[o]  = siz[ls] + siz[rs] + 1;
            int sums = numv[o];
            if(ls) maxv[o] = max(maxv[o], maxv[ls]), sums += rmax[ls];
            if(rs) maxv[o] = max(maxv[o], maxv[rs]), sums += lmax[rs];
            maxv[o] = max(maxv[o], sums);
            lmax[o] = max(lmax[ls], sumv[ls] + numv[o] + lmax[rs]);
            rmax[o] = max(rmax[rs], sumv[rs] + numv[o] + rmax[ls]);
        }
        inline void maintain(int o)
        {
            maxv[o] = max(numv[o], sumv[o]);
            lmax[o] = rmax[o] = max(0, sumv[o]);
        }
        inline void pushdown(int x)
        {
            int  ls = ch[x][0], rs = ch[x][1];
            if(lazy[x] != inf)
            {
                if(ls){ numv[ls] = lazy[ls] = lazy[x], sumv[ls] = siz[ls] * numv[ls]; maintain(ls); }
                if(rs){ numv[rs] = lazy[rs] = lazy[x], sumv[rs] = siz[rs] * numv[rs]; maintain(rs); }
                lazy[x] = inf;
            }
            if(tag[x])
            {
                swap(lmax[ls], rmax[ls]);   swap(lmax[rs], rmax[rs]);
                swap(ch[ls][0], ch[ls][1]); swap(ch[rs][0], ch[rs][1]);
                if(ls) tag[ls] ^= 1;
                if(rs) tag[rs] ^= 1;
                tag[x] = 0;
            }
        }
        void build(int l,int r,int fa,int &o)
        {
            if(l > r) return ;
            int mid = (l + r) >> 1;
            o = new_node();
            f[o] = fa, numv[o] = arr[mid], lazy[o] = inf;
            build(l, mid - 1, o, ch[o][0]);
            build(mid + 1, r, o, ch[o][1]);
            pushup(o); 
        }
    }T;
    inline int get(int x){ return ch[f[x]][1] == x;}
    inline void rotate(int x)
    {
        int old = f[x], oldf = f[old], which = get(x);
        ch[old][which] = ch[x][which ^ 1], f[ch[old][which]] = old;
        ch[x][which ^ 1] = old, f[old] = x, f[x] = oldf;
        if(oldf) 
            ch[oldf][ch[oldf][1] == old] = x;
        T.pushup(old); T.pushup(x);
    }
    inline void splay(int x,int &tar)
    {
        int a = f[tar];
        for(int fa; (fa = f[x]) != a; rotate(x))
            if(f[fa] != a) rotate(get(x) == get(fa) ? fa : x);
        tar = x;
    }
    inline int findx(int x, int top)
    {
        int cur = top;
        while(1)
        {
            T.pushdown(cur);
            int ls = ch[cur][0];
            if(x == siz[ls] + 1) return cur;
            if(x <= siz[ls])  cur = ch[cur][0];
            else x -= siz[ls] + 1, cur = ch[cur][1];
        }
        return 0;
    }
    inline void split(int &a, int nums, int &b)
    {
        if(nums == 0)
        {
            b = a, a = 0; return ;
        }
        if(nums == siz[a])
        {
            b = 0; return ;
        }
        int u = findx(nums, a);
        splay(u, a);
        b = ch[a][1], f[ch[a][1]] = 0 , ch[a][1] = 0;
        T.pushup(a);
    }
    inline void merge(int &a, int &b)
    {
        if(!a)
        {
            a = b; return ;
        }
        int u = findx(siz[a], a);
        splay(u, a);
        ch[a][1] = b, f[ch[a][1]] = a;
        T.pushup(a);
    }
    inline void Insert()
    {
        int pos, tot;
        scanf("%d%d",&pos,&tot);
        for(int i = 1;i <= tot; ++i) scanf("%d",&arr[i]);
        int a = 0, b = 0;
        split(root, pos, a);
        T.build(1, tot, 0, b);
        merge(root, b);
        merge(root, a);
    }
    inline void Delete()
    {
        int pos, tot;
        scanf("%d%d",&pos,&tot);
        int a , b;
        split(root, pos - 1, a);
        split(a, tot, b); 
        T.trash(a);    
        merge(root, b);
    }
    inline void Make_Same()
    {
        int pos, tot, c, a = 0, b = 0;
        scanf("%d%d%d",&pos,&tot,&c);
        split(root, pos - 1, a), split(a, tot, b);
        sumv[a] = siz[a] * c, lazy[a] = c, numv[a] = c;
        T.maintain(a);
        merge(root, a), merge(root, b);
    }
    inline void Reverse()
    {
        int pos, tot, a = 0, b = 0;
        scanf("%d%d",&pos,&tot);
        split(root, pos - 1, a); split(a, tot, b);
        tag[a] ^= 1;
        swap(lmax[a], rmax[a]), swap(ch[a][0], ch[a][1]); 
        merge(root, a), merge(root, b);
    }
    inline void Get_sum()
    {
        int pos, tot, a = 0, b = 0;
        scanf("%d%d",&pos,&tot);
        split(root, pos - 1, a), split(a, tot, b);
        printf("%d
    ",sumv[a]);
        merge(root, a), merge(root, b);
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        T.init();
        for(int i = 1;i <= n; ++i) scanf("%d",&arr[i]);
        T.build(1, n, 0, root);
        for(int i = 1;i <= m; ++i)
        {
            char str[30];
            scanf("%s",str);
            if(str[0] == 'I') Insert();
            if(str[0] == 'D') Delete();
            if(str[2] == 'K') Make_Same();
            if(str[0] == 'R') Reverse();
            if(str[0] == 'G') Get_sum();
            if(str[2] == 'X') printf("%d
    ",maxv[root]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    质数和分解(完全背包)
    CodeForces
    FZU
    FZU
    Pets(匈牙利算法)
    Construct a Matrix (矩阵快速幂+构造)
    绝世好题(线性dp)
    String painter (区间dp)
    Funny Positive Sequence (思维+前缀)
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845163.html
Copyright © 2011-2022 走看看