#include "garden.h"
#include "gardenlib.h"
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
vector<int> lead, cycSize;
vector<bool> targ, cyc;
vector<vector<int>> best, g, specDis;
void find_cycles() {
    vector<int> deg(n, 0);
    cyc.assign(n, true);
    for (int i = 0; i < n; i++) deg[lead[i]]++;
    queue<int> q;
    for (int i = 0; i < n; i++) {
        if (deg[i] == 0) q.push(i);
    }
    while (!q.empty()) {
        int curr = q.front();
        q.pop();
        cyc[curr] = false;
        deg[lead[curr]]--;
        if (deg[lead[curr]] == 0) q.push(lead[curr]);
    }
}
void get_cyc_dp() {
    cycSize.assign(n, 0);
    specDis.assign(n, vector<int>(2, -2));
    for (int i = 0; i < n; i++) {
        if (!cyc[i] || cycSize[i] != 0) continue;
        int curr = lead[i];
        int tot = 1;
        while (curr != i) {
            if (curr == 2 * k) {
                specDis[i][0] = tot;
            }
            if (curr == 2 * k ^ 1) {
                specDis[i][1] = tot;
            }
            tot++;
            curr = lead[curr];
        }
        if (curr == 2 * k) specDis[i][0] = 0;
        if (curr == 2 * k ^ 1) specDis[i][1] = 0;
        cycSize[i] = tot;
        int prev = i;
        curr = lead[i];
        while (curr != i) {
            specDis[curr][0] = max(-2, specDis[prev][0] - 1);
            specDis[curr][1] = max(-2, specDis[prev][1] - 1);
            if (specDis[curr][0] == -1) specDis[curr][0] = cycSize[i] - 1;
            if (specDis[curr][1] == -1) specDis[curr][1] = cycSize[i] - 1;
            cycSize[curr] = cycSize[i];
            prev = curr;
            curr = lead[curr];
        }
    }
}
void get_rest_dp() {
    vector<vector<int>> revG(n);
    vector<int> deg(n, 0);
    for (int i = 0; i < n; i++) {
        if (cyc[i] || cyc[lead[i]]) continue;
        revG[lead[i]].push_back(i);
        deg[i]++;
    }
    queue<int> q;
    for (int i = 0; i < n; i++) {
        if (cyc[i]) continue;
        if (deg[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int curr = q.front();
        q.pop();
        if (curr == 2 * k) {
            specDis[curr][0] = 0;
        }
        else {
            if (specDis[lead[curr]][0] == -2) continue;
            specDis[curr][0] = specDis[lead[curr]][0] + 1;
        }
        if (curr == 2 * k ^ 1) {
            specDis[curr][1] = 0;
        }
        else {
            if (specDis[lead[curr]][1] == -2) continue;
            specDis[curr][1] = specDis[lead[curr]][1] + 1;
        }
        cycSize[curr] = cycSize[lead[curr]];
        for (auto nxt: revG[curr]) {
            deg[nxt]--;
            if (deg[nxt] == 0) q.push(nxt);
        }
    }
}
void count_routes(int N, int M, int P, int R[][2], int Q, int G[]) {
    n = N;
    m = M;
    k = P;
    lead.assign(2*n, -1);
    best.assign(n, vector<int>(2, -1));
    for (int i = 0; i < m; i++) {
        int u = R[i][0];
        int v = R[i][1];
        if (best[u][0] == -1) best[u][0] = i;
        else if (best[u][1] == -1) best[u][1] = i;
        if (best[v][0] == -1) best[v][0] = i;
        else if (best[v][1] == -1) best[v][1] = i;
    }
    for (int u = 0; u < n; u++) {
        if (best[u][1] == -1) best[u][1] = best[u][0];
        int v = u ^ R[best[u][0]][0] ^ R[best[u][0]][1];
        if (best[u][0] != best[v][0]) {
            lead[2 * u] = 2 * v;
        }
        else lead[2 * u] = 2 * v ^ 1;
        v = u ^ R[best[u][1]][0] ^ R[best[u][1]][1];
        if (best[u][1] != best[v][0]) {
            lead[2 * u ^ 1] = 2 * v;
        }
        else lead[2 * u ^ 1] = 2 * v ^ 1;
    }
    n *= 2;
    targ.assign(n, false);
    targ[2 * k] = targ[2 * k ^ 1] = true;
    cyc.assign(n, false);
    find_cycles();
    get_cyc_dp();
    get_rest_dp();
    for (int i = 0; i < Q; i++) {
        int dis = G[i];
        int tot = 0;
        for (int j = 0; j < n; j+=2) {
            bool f = false;
            if (specDis[j][0] <= dis && specDis[j][0] != -2) {
                if ((dis - specDis[j][0]) % cycSize[j] == 0) f = true;
            }
            if (specDis[j][1] <= dis && specDis[j][1] != -2) {
                if ((dis - specDis[j][1]) % cycSize[j] == 0) f = true;
            }
            tot += f;
        }
        answer(tot);
    }
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |