社区讨论

开个O2 RE 不开就AC 人傻了

P4219[BJOI2014] 大融合参与者 4已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@locv5fm5
此快照首次捕获于
2023/10/30 20:15
2 年前
此快照最后确认于
2023/11/05 06:48
2 年前
查看原帖
C
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
const int N = 1e6 + 10;
const int mod = 1e9 + 7;

int read()
{
    int x = 0, 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();
    return x * f;
}

struct LCT
{
#define ls son[pos][0]
#define rs son[pos][1]

    int fa[N], sum[N], cnt[N], val[N], root, tcnt;
    int son[N][2];
    int exsiz[N], siz[N];
    int rev[N];
    void pushup(int pos)
    {
        siz[pos] = siz[ls] + siz[rs] + 1 + exsiz[pos];
    }
    bool isroot(int pos)
    {
        return pos != son[fa[pos]][0] && pos != son[fa[pos]][1];
    }
    void addtag(int pos)
    {
        rev[pos] ^= 1;
        swap(son[pos][0], son[pos][1]);
    }
    void pushdown(int pos)
    {
        if (rev[pos])
        {
            if (son[pos][1])
                addtag(son[pos][1]);
            if (son[pos][0])
                addtag(son[pos][0]);
            rev[pos] = 0;
        }
    }

    bool isson(int pos) { return pos == son[fa[pos]][1]; }

    void conect(int x, int d, int y)
    {
        son[x][d] = y;
        fa[y] = x;
    }

    void rorate(int x)
    {
        int y = fa[x], z = fa[y], dx = isson(x), dy = isson(y);

        fa[x] = z;
        if (!isroot(y))
            son[z][dy] = x;
        //conect(z, dy, x);
        conect(y, dx, son[x][dx ^ 1]);
        conect(x, dx ^ 1, y);
        pushup(y), pushup(x);
    }
    int st[N];
    void splay(int x)
    {
        int top;
        st[top = 1] = x;
        int u = x;
        while (!isroot(u))
            u = fa[u], st[++top] = u;
        while (top)
            pushdown(st[top--]);
        while (!isroot(x))
        {
            int y = fa[x];
            if (isroot(y))
            {
                rorate(x);
            }
            else if (isson(x) == isson(y))
                rorate(y), rorate(x);
            else
                rorate(x), rorate(x);
        }
        pushup(x);
    }
    void access(int x)
    {

        for (int i = 0; x; i = x, x = fa[x])
        {
            splay(x);
            exsiz[x] += siz[son[x][1]] - siz[i];
            son[x][1] = i;
            pushup(x);
        }
    }
    void makeroot(int x)
    {
        access(x), splay(x), addtag(x); // access 之后将没有右子树。然后把x变成根,把下面都翻转,这样x就是最小的元素了。
    }
    // int findroot(int x)
    // {
    //     access(x), splay(x);
    //     while (son[x][0])
    //         pushdown(x), x = son[x][0];
    //     return x;
    // }
    void split(int x, int y)
    {
        makeroot(x);
        access(y);
        splay(y);
    }
    bool link(int x, int y)
    {
        split(x, y);
        fa[x] = y;
        exsiz[y] += siz[x];
        pushup(y);
    }
    ll query(int x, int y)
    {
        split(x, y);
        // cout << siz[y] << " " << siz[x] << endl;
        return 1ll * (siz[y] - siz[x]) * (siz[x]);
    }

} t;

int main()
{
    int n = read(), q = read();
    while (q--)
    {
        char s[1];

        scanf("%s", s);
        int u = read(), v = read();
        if (s[0] == 'A')
        {
            t.link(u, v);
        }
        else
        {
            printf("%lld\n", t.query(u, v));
        }
    }
}

回复

4 条回复,欢迎继续交流。

正在加载回复...