[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\n",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\n",maxv[root]);
    }
    return 0;
}

  

posted @ 2018-09-19 20:46  EM-LGH  阅读(177)  评论(0编辑  收藏  举报