Submission #241968

#TimeUsernameProblemLanguageResultExecution timeMemory
241968abacabaWerewolf (IOI18_werewolf)C++14
0 / 100
500 ms167144 KiB
#include <iostream> #include <string> #include <unordered_map> #include <unordered_set> #include <cstring> #include <chrono> #include <vector> #include <map> #include <random> #include <set> #include <algorithm> #include <math.h> #include <cstdio> #include <stdio.h> #include <queue> #include <bitset> #include <cstdlib> #include <deque> #include <cassert> #include <stack> // #include "werewolf.h" using namespace std; #define mp make_pair #define f first #define se second #define pb push_back #define ppb pop_back #define emb emplace_back #define ll long long #define ull unsigned long long #define cntbit(x) __builtin_popcount(x) #define endl '\n' #define uset unordered_set #define umap unordered_map #define pii pair<int, int> #define ld long double #define pll pair<long long, long long> mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); template <typename T> inline T range(T l, T r) { return uniform_int_distribution<T>(l, r)(rng); } inline void setin(string s) { freopen(s.c_str(), "r", stdin); } inline void setout(string s) { freopen(s.c_str(), "w", stdout); } template <typename T> void Min(T &a, T b) { a = min(a, b); } template <typename T> void Max(T &a, T b) { a = max(a, b); } const int inf = 2e9; const int mod = 998244353; const int N = 2e5 + 15; const int L = 19; const int M = 4e5 + 15; int n, q; vector <int> g[N]; int l[M], r[M]; int k[M], tin[M], tout[M], tt, up[L][M]; int backtin[N]; struct dsu { int p[N], sz[N]; dsu() { for(int i = 0; i < N; ++i) p[i] = i, sz[i] = 1; } int find(int v) { if(v == p[v]) return v; return p[v] = find(p[v]); } void unio(int a, int b) { a = find(a); b = find(b); if(a != b) { if(sz[a] < sz[b]) swap(a, b); p[b] = a; sz[a] += sz[b]; } } } s, rt; struct segment_tree { multiset <int> t[N << 1]; // void update(int i, int val, int type) { // i += n; // if(type == 1) { // for(t[i].insert(val); i > 1; i >>= 1) // t[i >> 1].insert(val); // } // else { // for(t[i].erase(t[i].find(val)); i > 1; i >>= 1) // t[i >> 1].erase(t[i >> 1].find(val)); // } // } // bool get(int l, int r, int val) { // for(l += n, r += n + 1; l < r; l >>= 1, r >>= 1) { // if(l & 1) { // if(t[l].find(val) != t[l].end()) // return true; // ++l; // } // if(r & 1) { // --r; // if(t[r].find(val) != t[r].end()) // return true; // } // } // return false; // } void update(int pos, int val, int type, int v = 1, int tl = 0, int tr = n - 1) { if(type == 1) t[v].insert(val); else t[v].erase(t[v].find(val)); if(tl != tr) { int mid = tl + tr >> 1; if(pos <= mid) update(pos, val, type, v << 1, tl, mid); else update(pos, val, type, v << 1 | 1, mid + 1, tr); } } bool get(int l, int r, int val, int v = 1, int tl = 0, int tr = n - 1) { if(tl > r || tr < l || l > r) return false; if(tl >= l && tr <= r) return t[v].find(val) != t[v].end(); int mid = tl + tr >> 1; return get(l, r, val, v << 1, tl, mid) || get(l, r, val, v << 1 | 1, mid + 1, tr); } } t; struct query { int l, r, s, e, ind; bool operator < (const query &rhs) const { return r < rhs.r; } } qs[N]; vector <pii> e; int cur[N]; inline int getk(int v, int val) { for(int i = L - 1; i >= 0; --i) if(k[up[i][v]] >= val) v = up[i][v]; return v; } void build(int v, int p) { up[0][v] = p; for(int i = 1; i < L; ++i) up[i][v] = up[i-1][up[i-1][v]]; if(v < n) { tin[v] = tout[v] = tt++; } else { build(l[v], v); build(r[v], v); tin[v] = tin[l[v]]; tout[v] = tout[r[v]]; } } inline void build_reachability_tree() { sort(e.begin(), e.end(), [&](pii a, pii b) { return min(a.f, a.se) > min(b.f, b.se); }); int nw = n; for(int i = 0; i < n; ++i) cur[i] = k[i] = i; for(int i = 0; i < e.size(); ++i) { int u = e[i].f, v = e[i].se; if(rt.find(u) != rt.find(v)) { l[nw] = cur[rt.find(u)]; r[nw] = cur[rt.find(v)]; rt.unio(u, v); k[nw] = min(u, v); cur[rt.find(u)] = nw++; } } build(nw - 1, nw - 1); for(int i = 0; i < n; ++i) backtin[tin[i]] = i; for(int i = 0; i < n; ++i) t.update(tin[i], i, 1); } inline void add(int v) { for(int to : g[v]) if(to < v) { if(s.find(v) == s.find(to)) continue; t.update(tin[v], s.find(v), -1); t.update(tin[to], s.find(to), -1); s.unio(to, v); t.update(tin[v], s.find(v), 1); t.update(tin[to], s.find(to), 1); } } vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) { n = N, q = S.size(); vector<int> ans(q, 0); for(int i = 0; i < X.size(); ++i) { g[X[i]].pb(Y[i]), g[Y[i]].pb(X[i]); e.pb({X[i], Y[i]}); } build_reachability_tree(); for(int i = 0; i < q; ++i) qs[i] = {L[i], R[i], S[i], E[i], i}; sort(qs, qs + q); for(int i = 0, ptr = 0; i < q; ++i) { while(ptr < n && ptr <= qs[i].r) add(ptr++); int p = getk(qs[i].s, qs[i].l); ans[qs[i].ind] = t.get(tin[p], tout[p], s.find(qs[i].e)); } return ans; }

Compilation message (stderr)

werewolf.cpp: In member function 'void segment_tree::update(int, int, int, int, int, int)':
werewolf.cpp:135:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
             int mid = tl + tr >> 1;
                       ~~~^~~~
werewolf.cpp: In member function 'bool segment_tree::get(int, int, int, int, int, int)':
werewolf.cpp:147:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
         int mid = tl + tr >> 1;
                   ~~~^~~~
werewolf.cpp: In function 'void build_reachability_tree()':
werewolf.cpp:192:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < e.size(); ++i) {
                    ~~^~~~~~~~~~
werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:230:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < X.size(); ++i) {
                    ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...