Submission #90464

#TimeUsernameProblemLanguageResultExecution timeMemory
90464popovicirobertSpecial graph (IZhO13_specialg)C++14
0 / 100
13 ms12024 KiB
#include <bits/stdc++.h> #define lsb(x) (x & (-x)) #define ll long long #define ull unsigned long long #define ld long double // 217 // 44 using namespace std; const int MAXN = (int) 1e5; int nxt[MAXN + 1]; struct Fenwick { vector <int> arr; int n; inline void init(int _n) { n = _n; arr.resize(n + 1); } inline void update(int pos, int val) { for(int i = pos; i <= n; i += lsb(i)) { arr[i] += val; } } inline int query(int pos) { int ans = 0; for(int i = pos; i > 0; i -= lsb(i)) { ans += arr[i]; } return ans; } inline int sum(int l, int r) { return query(r) - query(l - 1); } }aib_cyc; Fenwick aib[MAXN + 1]; bool vis[MAXN + 1]; inline void get_cycle(vector <int> &cycle) { int nod = 1; vector <int> nodes; while(vis[nod] == 0) { nodes.push_back(nod); vis[nod] = 1; nod = nxt[nod]; } reverse(nodes.begin(), nodes.end()); while(nodes.back() != nod) { nodes.pop_back(); } swap(nodes, cycle); cycle.push_back(0); reverse(cycle.begin(), cycle.end()); memset(vis, 0, sizeof(vis)); } bool in_cyc[MAXN + 1]; int pos[MAXN + 1], id[MAXN + 1]; vector <int> g[MAXN + 1]; int first[MAXN + 1], last[MAXN + 1]; int sz[MAXN + 1], lvl[MAXN + 1]; void dfs(int nod, int x) { first[nod] = ++sz[x]; id[nod] = x; for(auto it : g[nod]) { lvl[it] = lvl[nod] + 1; dfs(it, x); } last[nod] = ++sz[x]; } inline int solve_cyc_cyc(int a, int b) { if(pos[a] <= pos[b]) { if(aib_cyc.sum(pos[a], pos[b] - 1) == 0) { return pos[b] - pos[a]; } return -1; } if(aib_cyc.sum(pos[a], aib_cyc.n) + aib_cyc.sum(1, pos[b]) == 0) { return aib_cyc.n - pos[a] + pos[b]; } return -1; } inline int solve_tree_tree(int a, int b, bool t) { if(id[a] != id[b]) { return -1; } if(first[b] <= first[a] && last[a] <= last[b] && aib[id[a]].sum(first[b] + t, first[a]) == 0) { return lvl[a] - lvl[b]; } return -1; } inline int solve_tree_cyc(int a, int b) { if(solve_cyc_cyc(nxt[id[a]], b) == -1 || solve_tree_tree(a, id[a], 0) == -1) { return -1; } return solve_cyc_cyc(nxt[id[a]], b) + solve_tree_tree(a, id[a], 0) + 1; } int main() { //ifstream cin("A.in"); //ofstream cout("A.out"); int i, n, m; ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> n; for(i = 1; i <= n; i++) { cin >> nxt[i]; } vector <int> cycle; get_cycle(cycle); int cyc_sz = (int) cycle.size() - 1; for(i = 1; i <= cyc_sz; i++) { id[cycle[i]] = cycle[i]; pos[cycle[i]] = i; vis[cycle[i]] = 1; in_cyc[cycle[i]] = 1; } for(i = 1; i <= n; i++) { if(vis[nxt[i]] == 0 && vis[i] == 0) { g[nxt[i]].push_back(i); } } for(i = 1; i <= n; i++) { if(vis[nxt[i]] == 1 && vis[i] == 0) { dfs(i, i); } } aib_cyc.init(cyc_sz); for(i = 1; i <= n; i++) { aib[i].init(sz[i]); } cin >> m; while(m > 0) { m--; int type, a, b; cin >> type >> a; if(type == 1) { if(in_cyc[a]) { aib_cyc.update(pos[a], 1); } else { aib[id[a]].update(first[a], 1); aib[id[a]].update(last[a], -1); } } else { cin >> b; int ans = -1; if(in_cyc[a] && in_cyc[b]) { ans = solve_cyc_cyc(a, b); } else if(!in_cyc[a] && !in_cyc[b]) { ans = solve_tree_tree(a, b, 1); } else if(in_cyc[b]) { ans = solve_tree_cyc(a, b); } cout << ans << "\n"; } } //cin.close(); //cout.close(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...