【Splay】bzoj 3223 文艺平衡树

来源:互联网 发布:windows informix 编辑:程序博客网 时间:2024/06/05 10:47

贴代码直接滚……我TM再也不想看见这玩意了………………

#include <iostream>#include <cstdio>#include <cstdlib>#define MAXN 150000using namespace std;struct tree{    int val,sz,cnt;    int s[2],f;    bool flag;}a[1100000];int root,tot = 0,ans = 0,n;bool son(int x) /**如果为false,则x为左儿子,否则为右儿子**/{    return a[a[x].f].s[1] == x;}void rejs(int x)    /**重新计算x的大小**/{    a[x].sz = a[a[x].s[0]].sz + a[a[x].s[1]].sz + a[x].cnt;}void point(int x,int y,bool z)  /**x下插入y,y是x的z儿子**/{    a[x].s[z] = y;    a[y].f = x;}void change(int x){    if(!a[x].flag)        return ;    swap(a[x].s[0],a[x].s[1]);    a[x].flag ^= 1;    a[a[x].s[0]].flag ^= 1;    a[a[x].s[1]].flag ^= 1;}void rot(int x){    change(a[x].f);    change(x);    int p = a[x].f;    bool d = son(x);    point(a[p].f,x,son(p));    point(p,a[x].s[d^1],d);    point(x,p,d^1);    rejs(p);    rejs(x);    if(a[x].f == 0)        root = x;}void splay(int x){    while(a[x].f != 0)    {        if(a[a[x].f].f == 0)            rot(x);        else if(a[a[a[x].f].f].f == 0)        {            rot(x);            rot(x);        }        else        {            if(son(x) == son(a[x].f))            {                rot(a[x].f);                rot(x);            }            else            {                rot(x);                rot(x);            }        }    }}int findn(int x){    int p = root;    while(p)    {        if(x > a[p].val)            p = a[p].s[1];        else if(x < a[p].val)            p = a[p].s[0];        else            return p;    }    return 0;}void ins(int x){    int w = root,f = 0;    int p = findn(x);    if(p)    {        a[p].cnt ++;        while(p != root)        {            rejs(p);            p = a[p].f;        }        rejs(root);        return ;    }    while(w)    {        f = w;        if(x < a[w].val)            w = a[w].s[0];        else            w = a[w].s[1];    }    a[++tot].val = x;    a[tot].cnt = 1;    if(f == 0)    {        root = tot;        rejs(root);        return ;    }    if(x < a[f].val)        point(f,tot,0);    else        point(f,tot,1);    splay(tot);}int near(int x,bool d){    if(a[x].s[d] != 0)    {        int p = a[x].s[d];        while(a[p].s[d^1])            p = a[p].s[d^1];        return p;    }    else if(son(x) == d^1)        return a[x].f;    else    {        int p = a[x].f;        while(son(p) == d)        {            if(p == root)                return 0;            p = a[p].f;        }        return a[p].f;    }}void cle(int x){    a[a[x].f].s[son(x)] = 0;    a[x].val = 0;    a[x].sz = 0;    rejs(a[x].f);    a[x].f = 0;}void del(int x){    int p = near(x,0);    int q = near(x,1);    if(!p || !q)    {        splay(x);        if(p == 0)        {            root = a[x].s[1];            a[a[x].s[0]].f = 0;        }        else        {            root = a[x].s[0];            a[a[x].s[0]].f = 0;        }        return ;    }    splay(p);    splay(q);    rot(p);    cle(x);}int findk(int x){    int p = root;    int k = a[a[p].s[0]].sz;    while(233)    {        if(a[p].flag)            k += a[a[p].s[1]].sz - a[a[p].s[0]].sz;        change(p);        if(x > k && x <= k + a[p].cnt)        {            return a[p].val;        }        if(x <= k)        {            p = a[p].s[0];            k -= a[a[p].s[1]].sz + a[p].cnt;        }        else        {            k += a[p].cnt;            p = a[p].s[1];            k += a[a[p].s[0]].sz;        }    }}void delk(int x){    x = findn(x);    splay(x);    ans += a[a[x].s[0]].sz + a[x].cnt - 1;    a[a[x].s[1]].f = 0;    root = a[x].s[1];}void rev(int l,int r){    if(l == 1 && r == n)    {        a[root].flag ^= 1;        return ;    }    if(l == 1)    {        splay(findk(r+1));        a[a[root].s[0]].flag ^= 1;        return ;    }    if(r == n)    {        splay(findk(l-1));        a[a[root].s[1]].flag ^= 1;        return ;    }    int p = findk(l-1);    int q = findk(r+1);    splay(p);    splay(q);    a[a[p].s[1]].flag ^= 1;}void dfs(int x){    if(x == 0)        return ;    change(x);    dfs(a[x].s[0]);    dfs(a[x].s[1]);}int main(){    int m,x,y;    scanf("%d%d",&n,&m);    for(int i = 1;i <= n;i ++)        ins(i);    for(int i = 1;i <= m;i++)    {        scanf("%d%d",&x,&y);        rev(x,y);    }    dfs(root);    for(int i = 1;i <= n;i ++)        cout << findk(i) << " ";    return 0;}
0 0
原创粉丝点击