LCA瞎搞做法求助
查看原帖
LCA瞎搞做法求助
427623
XiaoQuQu楼主2022/8/10 10:16

自己想了一个做法,大概意思是判断 xyx \to y 的路径上有没有对应的点,用了个树上前缀和,8pts WA,问问我这个程序(或者思路)有啥问题。

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e5 + 5;
char c[MAXN], ch;
int cnt1[MAXN], cnt2[MAXN], d[MAXN], sz[MAXN], f[MAXN][18], n, m, x, y;
vector<int> G[MAXN];

void dfs(int x, int fa) {
    // cout << "dfs visit (" << x << ")" << endl;
    cnt1[x] = cnt1[fa] + (c[x] == 'G');
    cnt2[x] = cnt2[fa] + (c[x] == 'H');
    d[x] = d[fa] + 1; f[x][0] = fa; 
    for (int i = 1; (1 << i) <= d[x]; ++i) {
        f[x][i] = f[f[x][i - 1]][i - 1];
    }
    for (auto v : G[x]) {
        if (v == fa) continue;
        // cout << "\t visit:" << v << endl;
        dfs(v, x);
    }
    // cout << "visit end" << endl;
}

int lca(int x, int y) {
    int dx = d[x], dy = d[y];
    if (dx != dy) {
        if (dx < dy) {
            swap(dx, dy); swap(x, y);
        }
        int dd = dx - dy;
        for (int i = 0; i <= __lg(n); ++i) {
            if (dd & (1 << i)) x = f[x][i];
        }
    }
    if (x == y) return x;
    for (int i = __lg(n); i >= 0; --i) {
        if (d[f[x][i]] <= 0) continue;
        if (f[x][i] == f[y][i]) continue;
        else x = f[x][i], y = f[y][i];
    }
    return f[x][0];
} 

int main(void) {
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) 
        cin >> c[i];
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        G[x].push_back(y); G[y].push_back(x);
    }
    dfs(1, 0);
    while (m--) {
        cin >> x >> y >> ch;
        int l = lca(x, y);
        if (ch == 'G')
            if (cnt1[x] - cnt1[l - 1] + cnt1[y] - cnt1[l] > 0) 
                cout << 1;
            else 
                cout << 0;
        else
            if (cnt2[x] - cnt2[l - 1] + cnt2[y] - cnt2[l] > 0) 
                cout << 1;
            else 
                cout << 0;
    }
    return 0;
}
2022/8/10 10:16
加载中...