Two force balanced tree - Tree Tree sets (sets Splay segment tree balanced tree)

Face questions

  Bzoj3196

Resolve

  Splay segment tree and two trees are nested together, almost equal to the constant INF, but eventually over luck

  Thinking is relatively simple, the maintenance of the original array subscripts a segment tree, then a segment in each tree node, to maintain a weight value of the corresponding section Splay. Briefly about the operation:

 0. extraction interval

  This operation is the foundation of 1,2,4,5 operation, in fact, relatively easy to implement, the segment tree, run a race, if asked interval contains a range of node coverage, just keep it in an array number of the node, and then return on the line

 1. queries within range of rank k

  Extraction interval, to find all the Splay interval, respectively, is smaller than the number of values ​​of k, a phase can Jia Houjia

 2. Query Interval k-th largest

  Extraction interval, find all Splay interval, because of how Splay trees, this operation is clearly not the same as a general Splay query, only half of the answer, transformed into a operation, and then check the ranking on the line

 3. Single-point modification

  To find the segment tree down all the nodes contain pos, these nodes corresponding Splay the original value by deleting, adding new value

 4. precursor seek

  Also find all Splay within range, respectively to find precursors, the precursor to the maximum output. But k may not Splay in, so we need to find k greater than or equal weights lowest node, it will rotate to the root, to find precursors, but may not be the precursor, is inserted in each of them Splay -inf, ranking queries remember to subtract

 The subsequent seek

  Similar operations precursor, k less than or equal to find the maximum value of the node weights, rotation to the root, to find a successor, and each of them remember Splay line insert inf

 

  Most operations are of their own YY, may not be very good, but my long and boring debugging code is not long, is not easy.

 The code (340 OK):

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005, inf = 2147483647;

template<class T> void read(T &re)
{
    re=0;
    T sign=1;
    char tmp;
    while((tmp=getchar())&&(tmp<'0'||tmp>'9')) if(tmp=='-') sign=-1;
    re=tmp-'0';
    while((tmp=getchar())&&(tmp>='0'&&tmp<='9')) re=(re<<3)+(re<<1)+(tmp-'0');
    re*=sign;
}

int n, m, root[maxn<<1], rt, a[maxn];
int tot, cnt, lson[maxn<<1], rson[maxn<<1], stak[maxn], top, s[maxn], snum;

struct Splay_tree{
    int fa, s[2], val, siz, num;
} p [maxn* 20];

void update(int x)
{
    int ls = tr[x].s[0], rs = tr[x].s[1];
    tr[x].siz = tr[ls].siz + tr[rs].siz + tr[x].num;
}

void Rotate(int x)
{
    int y = tr[x].fa, z = tr[y].fa, k = (tr[y].s[1] == x), w = (tr[z].s[1] == y), son = tr[x].s[k^1];
    tr[y].s[k] = son;tr[son].fa = y;
    tr[x].s[k^1] = y;tr[y].fa = x;
    tr[z].s[w] = x;tr[x].fa = z;
    update(y);update(x);
}

void Splay(int x, int to, int id)
{
    int y, z;
    while(tr[x].fa != to)
    {
        y = tr[x].fa;z = tr[y].fa;
        if(z != to)
            Rotate((tr[y].s[0] == x) ^ (tr[z].s[0] == y)? x: y);
        Rotate(x);
    }
    if(!to)
        root[id] = x;
}

void Insert(int x, int v)
{
    int now = root[x], ff = 0;
    while(now)
    {
        ff = now;
        tr[now].siz ++;
        if(tr[now].val == v)    break;
        now = tr[now].s[v>tr[now].val];
    }
    if(now)
        tr[now].num ++;
    else
    {
        if(snum)
            now = s[snum--];
        else
            now = ++cnt;
        tr[now].val = v;
        tr[ff].s[v>tr[ff].val] = now;
        tr[now].fa = ff;
        tr[now].num = 1;
        tr[now].siz = 1;
        tr[now].s[0] = tr[now].s[1] = 0;
    }
    Splay(now, 0, x);
}

void build(int &x, int l, int r)
{
    x = ++tot;
    root[x] = ++cnt;
    tr[root[x]].val = -inf;
    tr[root[x]].siz = tr[root[x]].num = 1;
    tr[0].s[1] = root[x];
    Insert(x, inf);
    for(int i = l; i <= r; ++i)
        Insert(x, a[i]);
    if(l == r)    return ;
    int mid = (l + r)>>1;
    build(lson[x], l, mid);
    build(rson[x], mid + 1, r); 
}

void Extract(int x, int l, int r, int L, int R)
{
    if(l <= L && R <= r)
    {
        stak[++top] = x;
        return ;
    }
    int mid = (L + R)>>1;
    if(l <= mid)
        Extract(lson[x], l, r, L, mid);
    if(mid < r)
        Extract(rson[x], l, r, mid + 1, R);
}

int Queryrk(int id, int x)
{
    int now = root[id], ret = 0;
    while(now)
    {
        int ls = tr[now].s[0], rs = tr[now].s[1];
        if(x < tr[now].val)
        {
            if(ls)
                now = ls;
            else
                break;
        }    
        else if(x == tr[now].val)
        {
            ret += tr[ls].siz ;
            break;
        }
        else
        {
            ret += tr[ls].siz + tr[now].num;
            if(rs)
                now = rs;
            else
                break;
        }
    }
    tr[0].s[1] = root[id];
    Splay(now, 0, id);
    return ret;
}

int work1(int x)
{
    int ret = -top;
    while(top)
    {
        ret += Queryrk(stak[top], x);
        top --;
    }
    return ret + 1;
}

int check(int x)
{
    int ret = 0;
    for(int i = 1; i <= top; ++i)
        ret += Queryrk(stak[i], x);
    return ret + 1;
}

int work2(int x)
{
    x += top;
    int l = 0, r = 1e8, mid, ret = 0;
    while(l <= r)
    {
        mid = (l + r)>>1;
        if(check(mid) <= x)
            ret = mid, l = mid + 1;
        else
            r = mid - 1;
    }
    top = 0;
    return ret;
}

int Find(int now, int x)
{
    while(1)
    {
        int ls = tr[now].s[0], rs = tr[now].s[1];
        if(tr[now].val == x)    return now;
        if(x < tr[now].val)    now = ls;
        else    now = rs;
    }
}

int Querypre(int now)
{
    now = tr[now].s[0];
    while(tr[now].s[1])    now = tr[now].s[1];
    return now;
}

int Querynxt(int now)
{
    now = tr[now].s[1];
    while(tr[now].s[0])    now = tr[now].s[0];
    return now;
}

void Modify(int x, int pos, int l, int r, int v)
{
    tr[0].s[1] = root[x];
    int y = Find(root[x], a[pos]);
    Splay(y, 0, x);
    int pre = Querypre(root[x]);
    int nxt = Querynxt(root[x]);
    Splay(pre, 0, x);Splay(nxt, pre, x);
    if(tr[y].num > 1)
    {
        tr[y].num --;
        tr[y].siz --;
    }
    else
    {
        s[++snum] = y;
        tr[nxt].s[0] = 0;
    }
    update(nxt);update(pre);
    Insert(x, v);
    if(l == r)
    {
        a[pos] = v;
        return ;
    }
    int mid = (l + r)>>1;
    if(pos <= mid)
        Modify(lson[x], pos, l, mid, v);
    else
        Modify(rson[x], pos, mid + 1, r, v);
}

int Findmx(int now, int x)
{
    int ret = 0;
    while(now)
    {
        int ls = tr[now].s[0], rs = tr[now].s[1];
        if(tr[now].val == x)
            return now;
        if(tr[now].val > x)
        {
            ret = now;
            now = ls;
        }
        else
            now = rs;
    }
    return ret;
}

int Findmn(int now, int x)
{
    int ret = 0;
    while(now)
    {
        int ls = tr[now].s[0], rs = tr[now].s[1];
        if(tr[now].val == x)
            return now;
        if(tr[now].val < x)
        {
            ret = now;
            now = rs;
        }
        else
            now = ls;
    }
    return ret;
}

int work3(int x)
{
    int ret = -inf;
    while(top)
    {
        tr[0].s[1] = root[stak[top]];
        int now = Findmx(root[stak[top]], x);
        Splay(now, 0, stak[top]);
        int pre = Querypre(root[stak[top]]);
        ret = max(ret, tr[pre].val);
        top--;
    }
    return ret;
}

int work4(int x)
{
    int ret = inf;
    while(top)
    {
        tr[0].s[1] = root[stak[top]];
        int now = Findmn(root[stak[top]], x);
        Splay(now, 0, stak[top]);
        int nxt = Querynxt(root[stak[top]]);
        ret = min(ret, tr[nxt].val);
        top--;
    }
    return ret;
}

int main()
{
    read(n);read(m);
    for(int i = 1; i <= n; ++i)
        read(a[i]);
    build(rt, 1, n);
    for(int i = 1; i <= m; ++i)
    {
        int opt, l, r, k, pos;
        read(opt);
        if(opt == 1)
        {
            read(l);read(r);read(k);
            Extract(rt, l, r, 1, n);
            printf("%d\n", work1(k));
        }
        else if(opt == 2)
        {
            read(l);read(r);read(k);
            Extract(rt, l, r, 1, n);
            printf("%d\n", work2(k));
        }
        else if(opt == 3)
        {
            read(pos);read(k);
            Modify(rt, pos, 1, n, k);
        }
        else if(opt == 4)
        {
            read(l);read(r);read(k);
            Extract(rt, l, r, 1, n);
            printf("%d\n", work3(k));
        }
        else
        {
            read(l);read(r);read(k);
            Extract(rt, l, r, 1, n);
            printf("%d\n", work4(k));
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Joker-Yza/p/11243378.html