社区讨论

WA 18pts 求调

P11369[Ynoi2024] 弥留之国的爱丽丝参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mjpskquv
此快照首次捕获于
2025/12/28 21:55
2 个月前
此快照最后确认于
2026/01/01 12:25
2 个月前
查看原帖
AC on #1, #4, #18, #19, #20, #24
做法和 这篇题解 大致一样。
CPP
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const int N = 5e4 + 10, M = 1e5 + 10, B = 250;

struct Edge {
    int u, v;
    bool col, f;
} e[M];

struct Ques {
    int op, x, y;
} que[M];

int n, m, q, deg[N], ct[2 * B + 10][2 * B + 10];
int dfn[N], low[N], tot, stk[N], top, scc[N], cnt;
bool f[N];
vector<int> g[N], G[N];
bitset<2 * B> vis[N], to[2 * B], now, goes[2 * B];

void topo_sort() {
    queue<int> que;
    for (int i = 1; i <= cnt; i++) {
        if (!deg[i]) que.push(i);
    }
    while (!que.empty()) {
        int u = que.front(); que.pop();
        for (int v : g[u]) {
            deg[v]--, vis[v] |= vis[u];
            if (!deg[v]) que.push(v);
        }
        g[u].clear();
    }
}

void tarjan(int x) {
    dfn[x] = low[x] = ++tot;
    f[x] = 1, stk[++top] = x;
    for (int y : g[x]) {
        if (!dfn[y]) tarjan(y), low[x] = min(low[x], low[y]);
        else if (f[y]) low[x] = min(low[x], dfn[y]);
    }
    if (dfn[x] == low[x]) {
        cnt++;
        while (1) {
            int k = stk[top--];
            scc[k] = cnt, f[k] = 0;
            if (k == x) break;
        }
    }
}

bool bfs(int st, int ed) {
    queue<int> que; que.push(st);
    now.set(), now[st] = 0;
    while (!que.empty()) {
        int u = que.front(); que.pop();
        bitset<2 * B> can = now & (goes[u] | to[u]);
        int pos = can._Find_first();
        // cout << u << ' ' << pos << ' ' << can << ' ' << now << ' ' << goes[u] << ' ' << to[u] << '\n';
        while (pos < 2 * B) {
            now[pos] = 0, que.push(pos);
            pos = can._Find_next(pos);
        }
    }
    return !now[ed];
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m >> q;
    for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v, e[i].col = 1;
    for (int i = 1; i <= q; i++) {
        cin >> que[i].op >> que[i].x;
        if (que[i].op == 2) cin >> que[i].y;
    }
    for (int i = 1; i <= q; ) {
        vector<int> pos, tmp;
        for (int j = 1; i <= q && j <= B; j++, i++) {
            if (que[i].op == 1) {
                e[que[i].x].f = 1;
                tmp.push_back(e[que[i].x].u);
                tmp.push_back(e[que[i].x].v);
            } else tmp.push_back(que[i].x), tmp.push_back(que[i].y);
        }

        for (int j = 1; j <= m; j++) {
            if (!e[j].f && e[j].col) g[e[j].v].push_back(e[j].u);
        }

        cnt = 0;

        for (int j = 1; j <= n; j++) {
            if (!dfn[j]) tarjan(j);
            G[j] = g[j];
        }

        // for (int j = 1; j <= n; j++) cout << scc[j] << ' ';
        // cout << '\n';

        for (int j = 0; j < tmp.size(); j++) pos.push_back(scc[tmp[j]]);
        sort(pos.begin(), pos.end());
        pos.erase(unique(pos.begin(), pos.end()), pos.end());

        for (int j = 1; j <= n; j++) g[j].clear();
        for (int j = 1; j <= n; j++) {
            for (int k : G[j]) {
                if (scc[j] != scc[k]) g[scc[j]].push_back(scc[k]), deg[scc[k]]++;
            }
            G[j].clear();
        }
        for (int j = 0; j < pos.size(); j++) vis[pos[j]][j] = 1;

        topo_sort();

        // for (int j = 1; j <= cnt; j++) {
        //     for (int k = 0; k < pos.size(); k++) cout << vis[j][k] << ' ';
        //     cout << '\n';
        // }

        for (int j = 0; j < pos.size(); j++) {
            for (int k = 0; k < pos.size(); k++) {
                if (vis[pos[j]][k]) goes[j][k] = 1;//, cout << j << ' ' << k << '\n';
            }
        }

        for (int j = 1; j <= m; j++) {
            if (e[j].f && e[j].col) {
                int p = lower_bound(pos.begin(), pos.end(), scc[e[j].u]) - pos.begin();
                int q = lower_bound(pos.begin(), pos.end(), scc[e[j].v]) - pos.begin();
                to[p][q] = 1, ct[p][q]++;
            }
            e[j].f = 0;
        }
        
        for (int j = max(i - B, 1); j < i; j++) {
            if (que[j].op == 1) {
                int p = lower_bound(pos.begin(), pos.end(), scc[e[j].u]) - pos.begin();
                int q = lower_bound(pos.begin(), pos.end(), scc[e[j].v]) - pos.begin();
                e[que[j].x].col ? ct[p][q]-- : ct[p][q]++;
                to[p][q] = bool(ct[p][q]), e[que[j].x].col ^= 1;
                // cout << i << ' ' << p << ' ' << q << ' ' << ct[p][q] << '\n';
            } else {
                que[j].x = lower_bound(pos.begin(), pos.end(), scc[que[j].x]) - pos.begin();
                que[j].y = lower_bound(pos.begin(), pos.end(), scc[que[j].y]) - pos.begin();
                // cout << j << ' ' << i << ' ' << que[j].x << ' ' << que[j].y << '\n';
                cout << (bfs(que[j].x, que[j].y) ? "YES\n" : "NO\n");
            }
        }

        for (int j = 0; j < pos.size(); j++) fill(ct[j], ct[j] + pos.size(), 0), to[j].reset(), goes[j].reset();
        for (int j = 1; j <= n; j++) dfn[j] = low[j] = scc[j] = 0, vis[j].reset();
        tot = cnt = 0;
    }
    return 0;
}

回复

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

正在加载回复...