zoukankan      html  css  js  c++  java
  • [BJOI2014]大融合(LCT)

    题面

    luogu

    bzoj是权限题..

    题解

    (LCT)维护子树信息

    因为(LCT)中有一些虚子树,(splay)维护不了.

    所以要新开一个数组来记录

    然后注意(link)

    是先(split(x,y))

    因为一般的(link)是先(makeroot(x))

    (fa[x] = y)

    然而,如果(y)之上还有节点,就无法实时更新

    想想,(split(x,y))是怎么操作的

     makeroot(x); access(y); splay(y); 
    

    这样(y)之上就没有节点了

    所以只要更新(y)这个点即可

    Code

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    const int N = 100010;
    int ch[N][2], fa[N], siz[N], val[N];
    bool rev[N];
    bool isroot(int x) {
        return (ch[fa[x]][0] != x && ch[fa[x]][1] != x);
    }
    #define get(x) (ch[fa[x]][1] == x)
    void pushup(int x) { siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1 + val[x]; }
    void rotate(int x) {
        int y = fa[x], z = fa[y], k = get(x);
        if (!isroot(y)) ch[z][get(y)] = x;
        fa[x] = z;
        ch[y][k] = ch[x][k ^ 1]; fa[ch[x][k ^ 1]] = y;
        ch[x][k ^ 1] = y; fa[y] = x;
        pushup(y);
        return ;
    }
    void putrev(int x) {
        swap(ch[x][0], ch[x][1]);
        rev[x] ^= 1;
    }
    void pushdown(int x) {
        if (rev[x]) {
            if (ch[x][0]) putrev(ch[x][0]);
            if (ch[x][1]) putrev(ch[x][1]);
            rev[x] = 0;
        }
    }
    int S[N], top;
    void splay(int x) {
        S[top = 1] = x;
        for (int i = x; !isroot(i); i = fa[i]) S[++top] = fa[i];
        for (int i = top; i; i--) pushdown(S[i]);
        while (!isroot(x)) {
            int y = fa[x];
            if (!isroot(y))
                (get(x) ^ get(y)) ? rotate(x) : rotate(y);
            rotate(x);
        }
        pushup(x);
    }
    void access(int x) {
        for (int y = 0; x; y = x, x = fa[x])
            splay(x), val[x] += siz[ch[x][1]] - siz[y], ch[x][1] = y, pushup(x);
    }
    void makeroot(int x) { access(x); splay(x); putrev(x); }
    void split(int x, int y) { makeroot(x); access(y); splay(y); }
    void link(int x, int y) {
        split(x, y);
        fa[x] = y;
        val[y] += siz[x];
        pushup(y);
    }
    int main() {
        int n, Q;
        read(n), read(Q);
        while (Q--) {
            char c; int x, y;
            scanf("%c", &c); read(x), read(y);
            if (c == 'A') link(x, y);
            else {
                split(x, y);
                printf("%d
    ", (val[x] + 1) * (val[y] + 1));
                //printf("%d
    ", (siz[y] - siz[x]) * siz[x]); 也可以
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10601420.html
Copyright © 2011-2022 走看看