bzoj5063

平衡树

6个操作做完当然GG了,其实只有两个操作,翻转[A+1,A+B],把这个区间放到C的后面,那么就是基本splay操作了,可是好久没打,又GG了,splay函数写错了。。。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
namespace IO 
{
    const int Maxlen = N * 50;
    char buf[Maxlen], *C = buf;
    int Len;
    inline void read_in()
    {
        Len = fread(C, 1, Maxlen, stdin);
        buf[Len] = '';
    }
    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 fread(long long &x) 
    {
        x = 0;
        long long 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;
struct node {
    int f, rev, sz;
    int ch[2];
} t[N];
int n, m, root;
int ans[N], size[N];
void update(int x)
{
    t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1;
}
bool wh(int x) 
{
    return x == t[t[x].f].ch[1];
}
void pushdown(int x)
{
    if(!t[x].rev) return;
    t[t[x].ch[0]].rev ^= 1;
    t[t[x].ch[1]].rev ^= 1;
    swap(t[x].ch[0], t[x].ch[1]);
    t[x].rev = 0;
}
void up(int x)
{
    if(t[x].f) up(t[x].f);
    pushdown(x);
}
int build(int l, int r, int f)
{
    if(l > r) return 0;
    int mid = (l + r) >> 1; 
    t[mid].f = f;
    t[mid].ch[0] = build(l, mid - 1, mid);
    t[mid].ch[1] = build(mid + 1, r, mid);
    update(mid);
    return mid;
}
void rotate(int x)
{
    int f = t[x].f, w = wh(x);
    t[x].f = t[f].f;
    t[t[f].f].ch[wh(f)] = x;
    t[f].ch[w] = t[x].ch[w ^ 1];
    t[t[x].ch[w ^ 1]].f = f;
    t[x].ch[w ^ 1] = f;
    t[f].f = x;
    update(f);
    update(x);
}
inline void splay(int x, int tar)
{
    for(; t[x].f != tar; rotate(x))
        if(t[t[x].f].f != tar) 
            rotate(wh(x) == wh(t[x].f) ? t[x].f : x);
    if(!tar) root = x;      
}
int find(int x, int k)
{
    pushdown(x);
    if(t[t[x].ch[0]].sz + 1 == k) return x;
    if(k <= t[t[x].ch[0]].sz) return find(t[x].ch[0], k);
    return find(t[x].ch[1], k - t[t[x].ch[0]].sz - 1);
}
int split(int l, int r)
{
    int x = find(root, l - 1), y = find(root, r + 1);
    splay(x, 0);
    splay(y, root);
    return y;
}
void dfs(int u)
{
    if(!u) return;
    pushdown(u);
    dfs(t[u].ch[0]);
    ans[++ans[0]] = u;
    dfs(t[u].ch[1]);
}
int main()
{
    read_in();
    fread(n);
    fread(m);
    root = build(1, n + 2, 0);
    while(m--)
    {
        int A, B, C;
        fread(A);
        fread(B);
        fread(C);
        int x = split(A + 2, A + B + 1), y = t[x].ch[0];
        t[y].rev ^= 1;
        t[y].f = t[x].ch[0] = 0;
        update(x);
        update(t[x].f);
        int z = split(C + 2, C + 1);
        t[y].f = z;
        t[z].ch[0] = y;
        update(z);
        update(t[z].f);
    }
    dfs(root);
    for(int i = 2; i < ans[0]; ++i) printf("%d ", ans[i] - 1);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/19992147orz/p/7868110.html