Submission #1153652

#TimeUsernameProblemLanguageResultExecution timeMemory
1153652hiderrTropical Garden (IOI11_garden)C++20
100 / 100
4827 ms49756 KiB
#include "garden.h" #include "gardenlib.h" #include <bits/stdc++.h> using namespace std; #define loop(i, a, b) for(int i = a; i <= b; i++) #define loop_rev(i, a, b) for(int i = a; i >= b; i--) #define all(x) x.begin(), x.end() #define sz(x) int(x.size()) #define pb push_back using ll = long long; int n, m, p, q; vector<vector<pair<int, int>>> min_edge; vector<vector<pair<int, int>>> graph; vector<vector<int>> edges; vector<int> act; vector<int> D1, D2, L, C; int get_dest(pair<int, int> edge) { return edges[edge.first][edge.second]; } pair<int, int> get_next(pair<int, int> edge) { int v = get_dest(edge); if(edge.first != min_edge[v][0].first) { return min_edge[v][0]; } else { return min_edge[v][1]; } } int get_id(pair<int, int> edge) { return edge.first + (m * edge.second); } constexpr int UNVISITED = (-2e9); constexpr int UNREACHABLE = (2e9); int timer = 0; int sgn(int val) { if(val < 0) return (-1); if(val == 0) return 0; return 1; } int lo = 1e9; void dfs_cyc(pair<int, int> edge) { int id = get_id(edge); act[id] = ++timer; auto nxt = get_next(edge); int nxt_id = get_id(nxt); if(act[nxt_id]) { C[id] = C[nxt_id] = (act[id] - act[nxt_id]) + 1; lo = act[nxt_id]; } else { if(C[nxt_id] == UNVISITED) { dfs_cyc(nxt); } } if(act[id] >= lo) { L[id] = 1; } if(lo == act[id]) { lo = 1e9; } C[id] = C[nxt_id]; act[id] = 0; } void dfs1(pair<int, int> edge) { int v = get_dest(edge); int id = get_id(edge); D1[id] = UNREACHABLE; if(v == p && edge.first == min_edge[v][0].first) { if(L[id] || L[get_id(get_next(edge))]) { D1[id] = 1; } else { D1[id] = (-1); } return; } auto nxt = get_next(edge); int new_id = get_id(nxt); if(D1[new_id] == UNVISITED) { dfs1(nxt); } if(D1[new_id] == UNREACHABLE) { D1[id] = UNREACHABLE; } else { D1[id] = D1[new_id] + sgn(D1[new_id]); } } void dfs2(pair<int, int> edge) { int v = get_dest(edge); int id = get_id(edge); D2[id] = UNREACHABLE; if(v == p && edge.first != min_edge[v][0].first) { if(L[id] || L[get_id(get_next(edge))]) { D2[id] = 1; } else { D2[id] = (-1); } return; } auto nxt = get_next(edge); int new_id = get_id(nxt); if(D2[new_id] == UNVISITED) { dfs2(nxt); } if(D2[new_id] == UNREACHABLE) { D2[id] = UNREACHABLE; } else { D2[id] = D2[new_id] + sgn(D2[new_id]); } } void count_routes(int N, int M, int P, int _edges[][2], int Q, int _G[]) { n = N, m = M, p = P, q = Q; edges.resize(m, vector<int>(2)); loop(i, 0, m-1) { loop(j, 0, 1) { edges[i][j] = _edges[i][j]; } } graph.resize(n); loop(i, 0, m-1) { int a = edges[i][0]; int b = edges[i][1]; graph[a].pb({ i, 1 }); graph[b].pb({ i, 0 }); } min_edge.resize(n, vector<pair<int, int>>(2, { 1e9, (-1) })); D1.resize(2 * m, UNVISITED); D2.resize(2 * m, UNVISITED); C.resize(2 * m, UNVISITED); act.resize(2 * m, 0); L.resize(2 * m, 0); loop(i, 0, n-1) { for(pair<int, int> state : graph[i]) { if(state < min_edge[i][0]) { min_edge[i][1] = min_edge[i][0]; min_edge[i][0] = state; } else if(state < min_edge[i][1]) { min_edge[i][1] = state; } } if(sz(graph[i]) == 1) { min_edge[i][1] = min_edge[i][0]; } } loop(i, 0, n-1) { dfs_cyc(min_edge[i][0]); } loop(i, 0, n-1) { auto e = min_edge[i][0]; if(D1[get_id(e)] == UNVISITED) { dfs1(e); } if(D2[get_id(e)] == UNVISITED) { dfs2(e); } assert(D2[get_id(e)] != UNVISITED); } loop(i, 0, n-1) { int id = get_id(min_edge[i][0]); cerr << "D1[" << i << "] = " << D1[id] << ", " << "D2[" << i << "] = " << D2[id] << ", " << "cycle_len[" << i << "] = " << C[id] << '\n'; } loop(qi, 0, q-1) { int k = _G[qi]; if(k == 0) { answer(1); continue; } int res = 0; loop(i, 0, n-1) { int id = get_id(min_edge[i][0]); bool cool = false; { int d = D1[id]; if(d != UNREACHABLE) { int c = C[id]; if(d > 0) { if(k % c == d % c && d <= k) { cool = true; ++res; } } else { if(k == -d) { cool = true; ++res; } } } } if(!cool) { int d = D2[id]; if(d != UNREACHABLE) { int c = C[id]; if(d > 0) { if(k % c == d % c && d <= k) { ++res; } } else { if(k == -d) { ++res; } } } } } answer(res); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...