蒟蒻才学的LCT 只有60pts 求调 蟹蟹٩('ω')و

P4114 Qtree1

Link_Cut_Y @ 2022-02-13 18:43:08

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define ls tr[x].s[0]
#define rs tr[x].s[1]

using namespace std;

const int N = 100010;

struct Tree
{
    int s[2], v, p;
    int rev, maxn;
}tr[N];

int stk[N], n;

void push_rev(int x)
{
    swap(ls, rs);
    tr[x].rev ^= 1;
}

void pushup(int x)
{
    tr[x].maxn = max(tr[x].v, max(tr[ls].maxn, tr[rs].maxn));
}

void pushdown(int x)
{
    if (tr[x].rev)
    {
        push_rev(ls), push_rev(rs);
        tr[x].rev = 0;
    }
}

bool is_root(int x)
{
    return tr[tr[x].p].s[0] != x && tr[tr[x].p].s[1] != x;
}

void push_all(int x)
{
//  int top = 0;
//  stk[ ++ top] = x;
//  while (!is_root(x)) x = tr[x].p, stk[ ++ top] = x;
//  while (top) pushdown(stk[top -- ]);

    if (!is_root(x)) push_all(tr[x].p); 
    pushdown(x);
}

void rotate(int x)
{
    int y = tr[x].p, z = tr[y].p;
    int k = tr[y].s[1] == x;

    if (!is_root(y)) tr[z].s[tr[z].s[1] == y] = x; tr[x].p = z;
    tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
    tr[x].s[k ^ 1] = y, tr[y].p = x;
    pushup(y), pushup(x);
}

void splay(int x)
{
    push_all(x);

    while (!is_root(x))
    {
        int y = tr[x].p, z = tr[y].p;
        if (!is_root(y)) rotate(((tr[y].s[1] == x) ^ (tr[z].s[1] == y)) ? x : y);
        rotate(x);
    }
}

void access(int x)
{
    for (int y = 0; x; y = x, x = tr[x].p)
    {
        splay(x);
        tr[x].s[1] = y;
        pushup(x);
    }
}

void make_root(int x)
{
    access(x);
    splay(x);
    push_rev(x);
}

void make_path(int x, int y)
{
    make_root(x);
    access(y);
    splay(x);
}

void link(int x, int y)
{
    make_root(x);
    tr[x].p = y;
}

int main()
{
//  freopen("Qtree.in", "r", stdin);
//  freopen("Qtree.out", "w", stdout);

    scanf("%d", &n);

    for (int i = 1; i <= n - 1; i ++ )
    {
        int u, v;
        scanf("%d%d%d", &u, &v, &tr[n + i].v);
        link(u, n + i), link(n + i, v);
    }

    char op[7];
    while (scanf("%s", op), *op != 'D')
    {
        int x, y;
        scanf("%d%d", &x, &y);
        if (*op == 'C') splay(n + x), tr[n + x].v = y, pushup(n + x);
        if (*op == 'Q') make_path(x, y), printf("%d\n", tr[x].maxn);
    }

    return 0;
}

/*
InputSample:

10
1 2 2
1 4 3
1 5 8
2 3 5
2 6 10
4 7 9
6 9 6
7 8 9
7 10 2
CHANGE 7 8
CHANGE 3 5
QUERY 3 9
CHANGE 2 9
QUERY 3 5
QUERY 1 4
QUERY 4 1
CHANGE 4 2
CHANGE 5 6
DONE

OutputSample:

10
5
9
9

Myoutput:

0
9
9
9
*/

by MC_dmAC @ 2022-02-13 18:56:15

冒昧地问一下,LCT是什么

本蒟蒻表示根本听不懂qaq


by 望月Asta @ 2022-02-13 19:17:09

  1. rotate() 里特判一下 tr[x].s[k ^ 1] ,如果 tr[x].s[k ^ 1]0 不能给 tr[0].p 赋值.

  2. 点开少了,n 个点加 n - 1 条边应该是 2e5 的 LCT 结点数.

  3. make_path(x,y) 应该是 make_root(x),access(y),splay(y) 然后输出 y 的最大值信息.


by Link_Cut_Y @ 2022-02-13 19:18:51

@MC_dmAC 动态树(Link_cut_tree)


by Link_Cut_Y @ 2022-02-13 19:19:14

@望月Asta 蟹蟹dalao 目前已A


by Link_Cut_Y @ 2022-02-13 19:19:51

是因为数据范围开小了


|