Submission #531953

#TimeUsernameProblemLanguageResultExecution timeMemory
5319534fectaInside information (BOI21_servers)C++17
52.50 / 100
351 ms150908 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define boost() cin.tie(0), cin.sync_with_stdio(0)

struct query {
    int t, u, v, i;
};

const int MN = 240005;

int n, q, u, v, sz[MN], vis[MN], num[MN], inc[MN], des[MN], id, top[MN], ans[MN], pre[MN], par[MN], freq[MN];
char c;
vector<int> nodes[MN];
vector<pii> a[MN];
vector<query> ch[MN * 10];

int size_of(int cur, int par) {
    sz[cur] = 1;
    for (pii nxt : a[cur]) {
        if (vis[nxt.f] || nxt.f == par) continue;
        sz[cur] += size_of(nxt.f, cur);
    }
    return sz[cur];
}

int get_centroid(int cur, int par, int cnt) {
    for (pii nxt : a[cur]) {
        if (vis[nxt.f] || nxt.f == par) continue;
        if (sz[nxt.f] > cnt) return get_centroid(nxt.f, cur, cnt);
    }
    return cur;
}

void dfs(int cur, int par, int len, int col, int D, int I, int T) {
    num[cur] = col;
    des[cur] = D;
    inc[cur] = I;
    top[cur] = T;
    pre[cur] = len;
    for (pii nxt : a[cur]) {
        if (vis[nxt.f] || nxt.f == par) continue;
        dfs(nxt.f, cur, nxt.s, col, D & (nxt.s < len), I & (nxt.s > len), T);
    }
}

void solve(int cur, vector<query> qs) {
    cur = get_centroid(cur, 0, size_of(cur, 0) / 2);
    //printf("%lld\n", cur);
    for (pii nxt : a[cur]) {
        if (vis[nxt.f]) continue;
        ch[++id].clear();
        dfs(nxt.f, cur, nxt.s, id, 1, 1, nxt.s);
    }
    for (query Q : qs) {
        if (Q.u == cur) {
            if (des[Q.v] && top[Q.v] < Q.i) ans[Q.i] = -1;
            else ans[Q.i] = 0;
        } else if (Q.v == cur) {
            if (inc[Q.u] && pre[Q.u] < Q.i) ans[Q.i] = -1;
            else ans[Q.i] = 0;
        } else if (num[Q.u] != num[Q.v]) {
            if (des[Q.v] && inc[Q.u] && top[Q.v] < top[Q.u] && pre[Q.u] < Q.i) ans[Q.i] = -1;
            else ans[Q.i] = 0;
        } else ch[num[Q.u]].push_back(Q);
    }
    vis[cur] = 1;
    for (pii nxt : a[cur]) {
        if (vis[nxt.f]) continue;
        solve(nxt.f, ch[num[nxt.f]]);
    }
}

int find(int x) {
    return x == par[x] ? x : par[x] = find(par[x]);
}

bool merge(int x, int y) {
    for (int p : nodes[x]) nodes[y].push_back(p);
    nodes[x] = nodes[y];
    for (int p : nodes[x]) freq[p]++;
    return true;
}

int32_t main() {
    boost();

    vector<query> qs;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) par[i] = i, freq[i] = 1, nodes[i] = {i};
    for (int i = 1; i < n + q; i++) {
        cin >> c >> u;
        if (c != 'C') cin >> v;
        if (c == 'S') {
            a[u].push_back({v, i});
            a[v].push_back({u, i});
            if (n <= 4000) merge(u, v);
            ans[i] = -2;
        } else if (c == 'Q') {
            if (u == v) ans[i] = -1;
            else qs.push_back({1, u, v, i}); //v to u must be increasing
        } else {
            ans[i] = freq[u];
        }
    }
    solve(1, qs);
    for (int i = 1; i < n + q; i++) {
        if (ans[i] == -2) continue;
        if (ans[i] == -1) printf("yes\n");
        else if (ans[i] == 0) printf("no\n");
        else printf("%lld\n", ans[i]);
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...