Submission #1326636

#TimeUsernameProblemLanguageResultExecution timeMemory
1326636SmuggingSpun늑대인간 (IOI18_werewolf)C++20
100 / 100
419 ms79516 KiB
#include "werewolf.h" #include<bits/stdc++.h> using namespace std; const int INF = 1e9; const int lim = 2e5 + 5; int n, m, q; vector<int>X, Y, S, E, L, R, g[lim]; namespace sub12{ vector<int>solve(){ vector<int>ans(q); for(int i = 0; i < q; i++){ vector<vector<bool>>f(n + 1, vector<bool>(2, false)); queue<pair<int, int>>q; q.emplace(S[i], 0); f[S[i]][0] = true; while(!q.empty()){ auto [s, c] = q.front(); q.pop(); if(c == 0 && L[i] <= s && R[i] >= s){ f[s][1] = true; q.emplace(s, 1); } for(int& j : g[s]){ int d = s ^ X[j] ^ Y[j]; if(((c == 0 & d >= L[i]) || (c == 1 && d <= R[i])) && !f[d][c]){ f[d][c] = true; q.emplace(d, c); } } } ans[i] = f[E[i]][1]; } return ans; } } namespace sub3{ bool check_subtask(){ if(m != n - 1){ return false; } for(int i = 1; i <= n; i++){ if(g[i].size() > 2){ return false; } } return true; } vector<int>solve(){ int tdfs = 0; vector<int>low(n + 1), low2v(n + 1), ans(q); function<void(int, int)>dfs; dfs = [&] (int s, int p){ low2v[low[s] = ++tdfs] = s; for(int& i : g[s]){ int d = X[i] ^ Y[i] ^ s; if(d != p){ dfs(d, s); } } }; for(int i = 1; i <= n; i++){ if(g[i].size() == 1){ dfs(i, -1); break; } } vector<pair<int, int>>st(n << 2 | 3); auto merge = [&] (pair<int, int>a, pair<int, int>b){ return make_pair(min(a.first, b.first), max(a.second, b.second)); }; function<void(int, int, int)>build; build = [&] (int id, int l, int r){ if(l == r){ st[id] = make_pair(low2v[l], low2v[l]); return; } int m = (l + r) >> 1; build(id << 1, l, m); build(id << 1 | 1, m + 1, r); st[id] = merge(st[id << 1], st[id << 1 | 1]); }; build(1, 1, n); function<int(int, int, int, int, int, const bool)>get; get = [&] (int id, int l, int r, int u, int v, const bool is_min){ if(l > v || r < u){ return is_min ? INF : -INF; } if(u <= l && v >= r){ return is_min ? st[id].first : st[id].second; } int m = (l + r) >> 1, left = get(id << 1, l, m, u, v, is_min), right = get(id << 1 | 1, m + 1, r, u, v, is_min); return is_min ? min(left, right) : max(left, right); }; for(int i = 0; i < q; i++){ int s = low[S[i]], e = low[E[i]]; if(s < e){ int low = s + 1, high = e, ps = s, pe = e; while(low <= high){ int mid = (low + high) >> 1; if(get(1, 1, n, s, mid, true) >= L[i]){ low = (ps = mid) + 1; } else{ high = mid - 1; } } low = s; high = e - 1; while(low <= high){ int mid = (low + high) >> 1; if(get(1, 1, n, mid, e, false) <= R[i]){ high = (pe = mid) - 1; } else{ low = mid + 1; } } ans[i] = pe <= ps; } else{ int low = e, high = s - 1, ps = s, pe = e; while(low <= high){ int mid = (low + high) >> 1; if(get(1, 1, n, mid, s, true) >= L[i]){ high = (ps = mid) - 1; } else{ low = mid + 1; } } low = e + 1; high = s; while(low <= high){ int mid = (low + high) >> 1; if(get(1, 1, n, e, mid, false) <= R[i]){ low = (pe = mid) + 1; } else{ high = mid - 1; } } ans[i] = pe >= ps; } } return ans; } } namespace sub4{ int tdfs = 0, lab[lim], low[lim], tail[lim], bit[lim], up[18][lim]; vector<array<int, 3>>query[lim]; int find_set(int i){ while(i != lab[i]){ i = lab[i] = lab[lab[i]]; } return i; } vector<int>krt[lim]; void dfs(int s){ low[s] = ++tdfs; for(int& d : krt[s]){ if(d != up[0][s]){ up[0][d] = s; dfs(d); } } tail[s] = tdfs; } void update(int p){ for(; p <= n; p += p & -p){ bit[p]++; } } int get(int p){ int ans = 0; for(; p > 0; p -= p & -p){ ans += bit[p]; } return ans; } vector<int>solve(){ iota(lab + 1, lab + n + 1, 1); for(int i = n; i > 0; i--){ for(int& ie : g[i]){ int j = find_set(X[ie] ^ Y[ie] ^ i); if(j > i){ krt[lab[j] = i].push_back(j); } } } memset(up[0], 0, sizeof(up[0])); dfs(1); for(int i = 1; i < 18; i++){ for(int j = 0; j <= n; j++){ up[i][j] = up[i - 1][up[i - 1][j]]; } } vector<pair<int, int>>tq1(q); for(int i = 0; i < q; i++){ int x = S[i]; for(int j = 17; j > -1; j--){ int nx = up[j][x]; if(nx >= L[i]){ x = nx; } } tq1[i] = make_pair(low[x], tail[x]); } vector<int>p1(n + 1); for(int i = 1; i <= n; krt[i++].clear()){ p1[i] = low[i]; } iota(lab + 1, lab + n + 1, 1); for(int i = 1; i <= n; i++){ for(int& ie : g[i]){ int j = find_set(X[ie] ^ Y[ie] ^ i); if(j < i){ krt[lab[j] = i].push_back(j); } } } memset(up[0], tdfs = 0, sizeof(up[0])); dfs(n); for(int i = 1; i < 18; i++){ for(int j = 1; j <= n; j++){ up[i][j] = up[i - 1][up[i - 1][j]]; } } for(int i = 1; i <= n; i++){ query[p1[i]].push_back({-1, low[i], -1}); } for(int i = 0; i < q; i++){ int x = E[i]; for(int j = 17; j > -1; j--){ int nx = up[j][x]; if(nx != 0 && nx <= R[i]){ x = nx; } } query[tq1[i].first - 1].push_back({low[x], tail[x], -i - 1}); query[tq1[i].second].push_back({low[x], tail[x], i}); } vector<int>ans(q, 0); memset(bit, 0, sizeof(bit)); for(int i = 1; i <= n; i++){ for(auto& [l, r, id] : query[i]){ if(l == -1){ update(r); } else if(id < 0){ ans[-id - 1] = get(r) - get(l - 1); } else{ ans[id] = get(r) - get(l - 1) > ans[id]; } } } return ans; } } vector<int>check_validity(int _n, vector<int>_X, vector<int>_Y, vector<int>_S, vector<int>_E, vector<int>_L, vector<int>_R){ swap(X, _X); swap(Y, _Y); swap(S, _S); swap(E, _E); swap(L, _L); swap(R, _R); m = X.size(); q = S.size(); for(int i = 0; i < m; i++){ g[++X[i]].emplace_back(i); g[++Y[i]].emplace_back(i); } for(int i = 0; i < q; i++){ S[i]++; E[i]++; L[i]++; R[i]++; } if((n = _n) <= 3000 && m <= 6000 && q <= 3000 && false){ return sub12::solve(); } if(sub3::check_subtask() && false){ return sub3::solve(); } return sub4::solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...