社区讨论

MnZn 求助,LCA16pts,孩子调吐了,求 dalao 帮助,关注为报

P5836[USACO19DEC] Milk Visits S参与者 3已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lo7p6mn0
此快照首次捕获于
2023/10/27 05:29
2 年前
此快照最后确认于
2023/10/27 05:29
2 年前
查看原帖
RT
CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>

using namespace std;

const int MAXN = 1e5 + 1e2;

inline int read()
{
    int x = 0; char ch = getchar();
    while ( !isdigit(ch) ) ch = getchar();
    while ( isdigit(ch) ) { x = (x << 1) + (x << 3) + (ch xor 48); ch = getchar(); }
    return x;
}

int n, m, cow[MAXN];
struct edge
{
    int to, next;
}e[MAXN << 1]; int head[MAXN], cnt;

inline void add (int u, int v) { e[++ cnt] = (edge) {v, head[u]}; head[u] = cnt; }
inline void input()
{
    n = read(), m = read();
    for (register int i = 1; i <= n; ++ i)
    {
        char c; cin >> c;
        if (c == 'G') cow[i] = 1;
        else cow[i] = 2;
    }
    for (register int i = 1, u, v; i < n; ++ i)
        u = read(), v = read(), add(u, v), add(v, u);
}

int f[MAXN][25][3], d[MAXN];

void dfs (int u, int fa)
{
    f[u][0][0] = fa;
    f[u][0][1] = (cow[u] == 1) or (cow[fa] == 1);
    f[u][0][2] = (cow[u] == 2) or (cow[fa] == 2);
    // for (register int i = 21; i >= 1; -- i)
    // {
    //     f[u][i][0] = f[ f[u][i - 1][0] ][i - 1][0];
    //     f[u][i][1] = f[u][i - 1][1] or f[ f[u][i - 1][0] ][i - 1][1];
    //     f[u][i][2] = f[u][i - 1][2] or f[ f[u][i - 1][0] ][i - 1][2];
    // }
    for (register int i = head[u], v; i; i = e[i].next)
        if ( (v = e[i].to) != fa) d[v] = d[u] + 1, dfs(v, u);
}
inline void LCA_init()
{
    d[1] = 1, dfs (1, 0);
    for (register int i = n; i >= 1; -- i)
        for (register int j = 1; j <= 21; ++ j)
        {
            f[i][j][0] = f[ f[i][j - 1][0] ][j - 1][0];
            f[i][j][1] = f[i][j - 1][1] or f[ f[i][j - 1][0] ][j - 1][1];
            f[i][j][2] = f[i][j - 1][2] or f[ f[i][j - 1][0] ][j - 1][2];
        }
}

inline bool find_LCA (int x, int y, int flag)
{
    if (d[x] > d[y]) swap(x, y);
    for (register int i = 21; i >= 0; -- i)
        if (d[ f[y][i][0] ] >= d[x])
        {
            if (f[y][i][flag]) return true;
            y = f[y][i][0];
        }
    if (x == y)
    {
        if (cow[x] == flag) return true;
        return false;
    }
    for (register int i = 21; i >= 0; -- i)
        if ( (1 << i) <= d[x])
            if (f[x][i][0] != f[y][i][0])
            {
                if (f[x][i][flag] or f[y][i][flag]) return true;
                x = f[x][i][0], y = f[y][i][0];
            }
    if (f[x][0][flag] or f[y][0][flag]) return true;
    return false;
}
inline void work()
{
    while (m --)
    {
        int a = read(), b = read(), type; char c; cin >> c;
        if (c == 'G') type = 1;
        else type = 2;
        bool flag = find_LCA(a, b, type);
        if (flag) printf("1");
        else printf("0");
    }
    puts ("");
}

int main()
{
    input();
    LCA_init();
    work();
    return 0;
}

回复

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

正在加载回复...