bzoj4825

LCT

昨天调试一天没出来,今天推倒重写还是gg了,内心崩溃照着源代码抄,结果发现自己把原树fa和splay的fa一起维护,各种re。。。

其实我们手玩一下,发现其实树的形态变化很小,那么就可以用lct维护了,查询就是相当于查询点到root的点权和,点权为1

删除什么的手画一下就行了

然后我们要用一个数组维护一下原树形态,因为splay是二叉树,可以很方便地维护树的形态,但是一般的树比较麻烦,因为删除儿子什么的的确很烦。这些信息不能再lct上维护,因为lct上fa会变化,里面的fa是splay的fa,不是原树的fa,就破坏了原树形态,所以不能这样维护

然后就是lct各种操作。。。几个月没写都忘了。。。

#include<bits/stdc++.h>
using namespace std;
const int N = 100010, inf = 1000000010;
namespace IO 
{
    const int Maxlen = N * 30;
    char buf[Maxlen], *C = buf;
    int Len;
    inline void read_in()
    {
        Len = fread(C, 1, Maxlen, stdin);
        buf[Len] = '\0';
    }
    inline void fread(int &x) 
    {
        x = 0;
        int f = 1;
        while (*C < '0' || '9' < *C) { if(*C == '-') f = -1; ++C; }
        while ('0' <= *C && *C <= '9') x = (x << 1) + (x << 3) + *C - '0', ++C;
        x *= f;
    }
    inline void read(int &x)
    {
        x = 0;
        int f = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + c - '0'; c = getchar(); }
        x *= f;
    }
    inline void read(long long &x)
    {
        x = 0;
        long long f = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = (x << 1ll) + (x << 3ll) + c - '0'; c = getchar(); }
        x *= f;
    } 
} using namespace IO;
int m, opt, cnt, key, root;
set<pair<int, int> > s; 
namespace LCT 
{
    int st[N];
    struct node {
        int size, l, r, c[2], fa, tag;
    } t[N];
    inline bool wh(int x) { return t[t[x].fa].c[1] == x; }
    inline void update(int x) { t[x].size = t[t[x].c[0]].size + t[t[x].c[1]].size + 1; }
    inline bool isroot(int x) { return t[t[x].fa].c[0] != x && t[t[x].fa].c[1] != x; }
    inline void pushdown(int x)
    {
        if(!t[x].tag) return;
        swap(t[x].c[0], t[x].c[1]);
        t[t[x].c[0]].tag ^= 1;
        t[t[x].c[1]].tag ^= 1; 
        t[x].tag ^= 1;
    }
    inline void up(int x)
    {
        int top = 0;
        st[++top] = x;
        while(!isroot(x)) 
        {
            x = t[x].fa;
            st[++top] = x;
        }
        for(int i = top; i; --i) pushdown(st[i]);
    }
    inline void rotate(int x)
    {
        int y = t[x].fa, z = t[y].fa, w = wh(x);
        t[x].fa = z;
        if(!isroot(y)) t[z].c[wh(y)] = x;
        t[y].c[w] = t[x].c[w ^ 1];
        t[t[x].c[w ^ 1]].fa = y;
        t[x].c[w ^ 1] = y;
        t[y].fa = x;
        update(y);
        update(x);
    }
    inline void splay(int x)
    {
        up(x);
        while(!isroot(x))
        {
            if(!isroot(t[x].fa)) rotate(wh(x) == wh(t[x].fa) ? t[x].fa : x);
            rotate(x);
        }
    }
    inline void access(int u)
    {
        for(int f = 0; u; f = u, u = t[u].fa) 
        {
            splay(u);
            t[u].c[1] = f;
            update(u);
        }
    }
    inline void rever(int u)
    {
        access(u);
        splay(u);
        t[u].tag ^= 1; 
    }
    inline void link(int u, int v)
    {
        if(!u || !v) return;
        rever(u);
        t[u].fa = v;
    }
    inline void cut(int u, int v)
    {
        if(!u || !v) return;
        rever(u);
        access(v);
        splay(v);
        t[v].c[0] = t[u].fa = 0;
        update(v);
    }
    inline void que(int u)
    {
        rever(root);
        access(u);
        splay(u);
        printf("%d\n", t[u].size);
    }
} using LCT :: link; using LCT :: cut; using LCT :: que; 
struct info {
    int l, r, fa;
} t[N];    
inline void insert(int key) 
{
    pair<int, int> o = make_pair(key, ++cnt);
    set<pair<int, int> > :: iterator it1, it2;
    it1 = it2 = s.insert(o).first;
    int u = 0, v = 0, x = cnt;
    if(it1 != s.begin()) u = (--it1) -> second;
    if(++it2 != s.end()) v = it2 -> second;
    if(u == 0 && v == 0) root = x;
    else if(v && t[v].l == 0) 
    {
        t[v].l = x;
        t[x].fa = v;
        link(v, cnt);
    }
    else if(u && t[u].r == 0)
    {
        t[u].r = x;
        t[x].fa = u;
        link(u, cnt);
    }
    que(cnt);
}
inline void splay_min()
{
    int u = s.begin() -> second, r = t[u].r, p = t[u].fa;
    que(u);
    if(u == root) return;
    cut(u, p);
    cut(u, r);
    link(p, r);
    link(u, root);
    t[u].r = root;
    t[root].fa = u;
    t[r].fa = p;
    t[p].l = r;
    root = u; 
}
inline void splay_max()
{
    set<pair<int, int> > :: iterator it = s.end();
    int u = (--it) -> second, l = t[u].l, p = t[u].fa;
    que(u);
    if(u == root) return;
    cut(u, p);
    cut(u, l);
    link(p, l);
    link(u, root);
    t[u].l = root;
    t[root].fa = u;
    t[l].fa = p;
    t[p].r = l;
    root = u; 
}
inline void del_min()
{
    set<pair<int, int> > :: iterator it = s.begin();
    int u = it -> second, r = t[u].r, p = t[u].fa;
    que(u);
    if(u == root)
    {
        cut(u, r);
        t[r].fa = 0;
        root = r;
    }
    else
    {
        cut(u, p);
        cut(u, r);
        link(p, r);
        t[r].fa = p;
        t[p].l = r;
    }
    s.erase(it);
}
inline void del_max()
{
    set<pair<int, int > > :: iterator it = s.end();
    int u = (--it) -> second, l = t[u].l, p = t[u].fa;
    que(u);
    if(u == root)
    {
        cut(u, l);
        t[l].fa = 0;
        root = l;
    }
    else
    {
        cut(u, p);
        cut(u, l);
        link(p, l);
        t[l].fa = p;
        t[p].r = l;
    }
    s.erase(it);
}
int main()
{
//    read_in();
    read(m);
    while(m--)
    {
        read(opt);
        if(opt == 1) read(key), insert(key);
        if(opt == 2) splay_min();
        if(opt == 3) splay_max();
        if(opt == 4) del_min();
        if(opt == 5) del_max(); 
    }
    return 0;
}
View Code

 

posted @ 2017-08-17 14:25  19992147  阅读(78)  评论(0编辑  收藏