Plantilla de extensión de doble giro

#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<iomanip>
#include<algorithm>
#include<unordered_map>
#include<string>
#include<cmath>
#include<cstdio>
#include<fstream>
#include<time.h>
#define inf 0x3f3f3f3f
#define lson rt<<1
#define rson rt<<1|1
#define fmid (tree[rt].l + tree[rt].r) / 2

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const ll mod = 998244353;
const double eps = 1e-8;
const double PI = acos(-1);
#define MOD(a, b) a >= b ? a % b + b : a
#define random(a,b) (rand()%(b-a+1)+a)
void acc_ios()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
}

struct node
{
    
    
    int f, sub_size, cnt, value, tag;
    int son[2];
}tree[maxn];//
int a[maxn], root, tot;
bool which(int x)
{
    
    
    return x == tree[tree[x].f].son[1];
}

void update(int x)
{
    
    
    if(x)
    {
    
    
        tree[x].sub_size = tree[x].cnt;
        if(tree[x].son[0]) tree[x].sub_size += tree[tree[x].son[0]].sub_size;
        if(tree[x].son[1]) tree[x].sub_size += tree[tree[x].son[1]].sub_size;
    }
}

void pushdown(int x)
{
    
    
    if(x && tree[x].tag)
    {
    
    
        tree[tree[x].son[0]].tag ^= 1;
        tree[tree[x].son[1]].tag ^= 1;
        swap(tree[x].son[1], tree[x].son[0]);
        tree[x].tag = 0;
    }
}

void Rotate(int x)
{
    
    
    int fnow = tree[x].f;
    int ffnow = tree[fnow].f;
    pushdown(x);
    pushdown(fnow);
    bool c = which(x);
    tree[fnow].son[c] = tree[x].son[c^1];
    tree[tree[fnow].son[c]].f = fnow;
    tree[fnow].f = x;
    tree[x].f = ffnow;
    tree[x].son[c^1] = fnow;
    if(ffnow)
    {
    
    
        tree[ffnow].son[tree[ffnow].son[1] == fnow] = x;
    }
    update(fnow);
}

void splay(int x, int goal)
{
    
    
    for(int fa; (fa = tree[x].f) != goal; Rotate(x))
    {
    
    
        if(tree[fa].f != goal)
        {
    
    
            Rotate(which(x) == which(fa) ? fa : x);
        }
    }
    if(goal == 0)
        root = x;
}

int build_tree(int l, int r, int fa)
{
    
    
    if(l > r) return 0;
    int mid = (l + r) >> 1;
    int now = ++tot;
    tree[now].f = fa;
    tree[now].son[0] = tree[now].son[1] = 0;
    tree[now].cnt = 1;
    tree[now].value = a[mid];
    tree[now].sub_size = 1;
    tree[now].son[0] = build_tree(l, mid - 1, now);
    tree[now].son[1] = build_tree(mid + 1, r, now);
    update(now);
    return now;
}

int Find(int x) //查询第x大的节点
{
    
    
    int now = root;
    while(1)
    {
    
    
        pushdown(now);
        if(x <= tree[tree[now].son[0]].sub_size)
        {
    
    
            now = tree[now].son[0];
        }
        else
        {
    
    
            x -= tree[tree[now].son[0]].sub_size + 1;
            if(!x) return now;
            now = tree[now].son[1];
        }
    }
}

void Reverse(int x, int y)
{
    
    
    int l = x - 1;
    int r = y + 1;
    l = Find(l);
    r = Find(r);
    splay(l, 0);
    splay(r, l);
    int pos = tree[root].son[1];
    pos = tree[pos].son[0];
    tree[pos].tag ^= 1;
}

void dfs(int now)
{
    
    
    pushdown(now);
    if(tree[now].son[0]) dfs(tree[now].son[0]);
    if(tree[now].value != -inf && tree[now].value != inf)
    {
    
    
        printf("%d ", tree[now].value);
    }
    if(tree[now].son[1]) dfs(tree[now].son[1]);
}

void Inser(int x) //添加值为x的点
{
    
    int fa = 0, u = root;
    while(u != 0&& x != tree[u].value)
    {
    
    
        fa = u;
        u = tree[u].son[x > tree[u].value];
    }
    if(u)
        tree[u].cnt++;
    else
    {
    
    
        u = ++tot;
        if(fa == 0)
            root = u;
        else
            tree[fa].son[x > tree[fa].value] = u;
        tree[u].value = x;
        tree[u].f = fa;
        tree[u].cnt = 1;
        tree[u].sub_size = 1;
    }
    splay(u, 0);
}

int main()
{
    
    
    //acc_ios();
    int n, m;
    scanf("%d%d", &n, &m);
    a[1] = -inf;
    a[n + 2] = inf;
    Inser(-inf);
    Inser(inf);
    //printf("%d\n", root);
    for(int i = 1; i <= n; i++)
    {
    
    
        //a[i + 1] = i;
        Inser(i);
    }
    //root = build_tree(1, n + 2, 0);
    for(int i = 0; i < m; i++)
    {
    
    
        int x, y;
        scanf("%d%d", &x, &y);
        Reverse(x + 1, y + 1);
        //printf("%d\n", tot);
    }
    dfs(root);
    return 0;
}



Supongo que te gusta

Origin blog.csdn.net/weixin_43891021/article/details/108111858
Recomendado
Clasificación