Submission #939228

#TimeUsernameProblemLanguageResultExecution timeMemory
939228Zero_OPWerewolf (IOI18_werewolf)C++14
0 / 100
434 ms110400 KiB
#include<bits/stdc++.h> using namespace std; using int64 = int64_t; #define REP(i, n) for(int i = 0, _n = n; i < _n; ++i) #define REPD(i, n) for(int i = n - 1; i >= 0; --i) #define FOR(i, l, r) for(int i = l, _r = r; i <= _r; ++i) #define FORD(i, r, l) for(int i = r, _l = l; i >= _l; --i) #define left __left #define right __right #define prev __prev #define next __next #define div __div #define pb push_back #define pf push_front #define sz(v) (int)v.size() #define range(v) begin(v), end(v) #define compact(v) v.erase(unique(range(v)), end(v)) #define debug(v) "[" #v " = " << (v) << "]" template<typename T> bool minimize(T& a, const T& b){ if(a > b){ a = b; return true; } return false; } template<typename T> bool maximize(T& a, const T& b){ if(a < b){ a = b; return true; } return false; } template<int dimension, class T> struct vec : public vector<vec<dimension - 1, T>> { static_assert(dimension > 0, "Dimension must be positive !\n"); template<typename... Args> vec(int n = 0, Args... args) : vector<vec<dimension - 1, T>>(n, vec<dimension - 1, T>(args...)) {} }; template<class T> struct vec<1, T> : public vector<T> { vec(int n = 0, T val = T()) : vector<T>(n, val) {} }; struct ReachabilityTree{ int number_nodes, timer_dfs; vector<int> tin, tout, order, lab; vector<vector<int>> adj; ReachabilityTree(int n, int m){ number_nodes = n; timer_dfs = -1; tin = vector<int>(n + m); tout = vector<int>(n + m); lab = vector<int>(n + m, -1); adj = vector<vector<int>>(n + m); order = vector<int>(); } int find_root(int u){ return lab[u] < 0 ? u : (lab[u] = find_root(lab[u])); } void unite(int u, int v){ u = find_root(u); v = find_root(v); adj[number_nodes].pb(u); if(u != v) adj[number_nodes].pb(v); lab[u] = number_nodes; lab[v] = number_nodes; ++number_nodes; } void dfs(int u){ tin[u] = ++timer_dfs; order.pb(u); for(int v : adj[u]){ dfs(v); } tout[u] = timer_dfs; } void process(){ dfs(number_nodes - 1); } }; struct Fenwick{ vector<int> bit; Fenwick(int n) : bit(n + 1, 0) {} void update(int id, int val){ for(; id < sz(bit); id += id & (-id)){ bit[id] += val; } } int query(int id){ int sum = 0; for(; id > 0; id -= id & (-id)){ sum += bit[id]; } return sum; } int get_range(int l, int r){ return query(r) - query(l - 1); } }; vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> T, vector<int> L, vector<int> R){ int n = N; int m = sz(X); int q = sz(S); vec<2, int> adj(n); REP(i, m){ int u = X[i], v = Y[i]; adj[u].pb(v); adj[v].pb(u); } ReachabilityTree from(n, m), until(n, m); vector<vector<int>> sweep_from(n), sweep_until(n); vector<int> query_from(q), query_until(q); REP(i, q){ sweep_from[L[i]].pb(i); sweep_until[R[i]].pb(i); } REPD(i, n){ for(int j : adj[i]){ if(j >= i){ from.unite(i, j); } } for(int id : sweep_from[i]){ query_from[id] = from.find_root(S[id]); } } REP(i, n){ for(int j : adj[i]){ if(j <= i){ until.unite(i, j); } } for(int id : sweep_until[i]){ query_until[id] = until.find_root(T[id]); } } from.process(); cout << '\n'; until.process(); vector<int> left(q), right(q); vector<vector<pair<int, int>>> sweep(n + m); REP(i, q){ int l1 = from.tin[query_from[i]]; int r1 = from.tout[query_from[i]]; left[i] = until.tin[query_until[i]]; right[i] = until.tout[query_until[i]]; if(l1 > 0) sweep[l1 - 1].pb(make_pair(i, -1)); sweep[r1].pb(make_pair(i, +1)); } auto is_node = [&](int u){ return -1 < u && u < n; }; vector<int> occur(n); REP(i, sz(from.order)){ int u = from.order[i]; if(is_node(u)){ occur[u] = i; } } vector<int> ans(q); Fenwick BIT(n + m); REP(i, n + m){ int u = until.order[i]; if(is_node(u)){ BIT.update(occur[u] + 1, 1); } for(const auto& iter : sweep[i]){ int id = iter.first, sign = iter.second; ans[id] += sign * BIT.get_range(left[id] + 1, right[id] + 1); } } REP(i, q){ minimize(ans[i], 1); } cout << '\n'; return ans; } //#define Zero_OP //turn off when submitting #ifdef Zero_OP void init(void); void process(void); int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int T = 1; //cin >> T; while(T--) { init(); process(); } return 0; } void init(){ } void process(){ vector<int> ans = check_validity(6, {5, 1, 1, 3, 3, 5}, {1, 2, 3, 4, 0, 2}, {4, 4, 5}, {2, 2, 4}, {1, 2, 3}, {2, 2, 4}); REP(i, sz(ans)){ cout << ans[i] << ' '; } cout << '\n'; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...