제출 #1265893

#제출 시각아이디문제언어결과실행 시간메모리
1265893canhnam357늑대인간 (IOI18_werewolf)C++20
100 / 100
1415 ms231888 KiB
#include "werewolf.h" #include <bits/stdc++.h> using namespace std; #define all(x) x.begin(), x.end() struct FakeFenwick { vector<vector<int>> fw, val; int n; FakeFenwick() {} FakeFenwick(int n) : n(n), val(n + 1, vector<int>()), fw(n + 1) {} bool iscc = 0; void fakeU(int x, int y) { iscc = 0; for (; x <= n; x += x & -x) val[x].push_back(y); } void cc() { if (iscc) return; for (int x = 1; x <= n; x++) { sort(all(val[x])); val[x].erase(unique(all(val[x])), val[x].end()); fw[x].resize(val[x].size() + 1); } iscc = 1; } void update(int x, int y, int v) { assert(iscc); for (; x <= n; x += x & -x) { int yy = upper_bound(all(val[x]), y) - val[x].begin(); for (; yy <= val[x].size(); yy += yy & -yy) { fw[x][yy] += v; } } } int get(int x, int y) { assert(iscc); int res = 0; for (; x; x -= x & -x) { int yy = upper_bound(all(val[x]), y) - val[x].begin(); for (; yy; yy -= yy & -yy) { res += fw[x][yy]; } } return res; } int get(int x1, int y1, int x2, int y2) { return get(x2, y2) - get(x2, y1 - 1) - get(x1 - 1, y2) + get(x1 - 1, y1 - 1); } }; struct dsu { int N, t; vector<vector<int>> adj, st; vector<int> par, pos, in, out; dsu() {} dsu(int N) { this->N = N; par.resize(N); iota(all(par), 0); adj.resize(N); pos.resize(N); in.resize(N); out.resize(N); } int find(int u) { return u == par[u] ? u : par[u] = find(par[u]); } void join(vector<int> v) { set<int> s; for (int i : v) s.insert(find(i)); par.push_back(N); adj.push_back({}); pos.push_back(-1); in.push_back(-1); out.push_back(-1); for (int i : s) par[i] = N, adj[N].push_back(i); N++; } void dfs(int u) { //cout << u << ' '; in[u] = t++; for (int v : adj[u]) { st[v][0] = u; dfs(v); } out[u] = t; //cout << u << ' '; } void dfs() { st = vector<vector<int>>(N, vector<int>(20)); t = 1; dfs(N - 1); st[N - 1][0] = N - 1; for (int i = 1; i < 20; i++) { for (int j = 0; j < N; j++) st[j][i] = st[st[j][i - 1]][i - 1]; } } int get(int u, int k) { for (int i = 19; i >= 0; i--) { if (st[u][i] <= k) u = st[u][i]; } return u; } }; vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) { vector<vector<int>> adj(N); int M = X.size(); for (int i = 0; i < M; i++) { adj[X[i]].push_back(Y[i]); adj[Y[i]].push_back(X[i]); } int Q = S.size(); vector<int> res(Q); dsu dsuL(N), dsuR(N); for (int i = N - 1; i >= 0; i--) { vector<int> v = {i}; for (int j : adj[i]) if (j > i) v.push_back(j); dsuL.join(v); } for (int i = 0; i < N; i++) { vector<int> v = {i}; for (int j : adj[i]) if (j < i) v.push_back(j); dsuR.join(v); } //out << "LEFT "; dsuL.dfs(); //cout << "\nRIGHT "; dsuR.dfs(); //cout << '\n'; FakeFenwick tree(N + M + 5); for (int i = 0; i < N; i++) { int x = dsuL.in[i], y = dsuR.in[i]; //cout << x << ' ' << y << '\n'; tree.fakeU(x, y); } tree.cc(); for (int i = 0; i < N; i++) { int x = dsuL.in[i], y = dsuR.in[i]; tree.update(x, y, 1); } for (int i = 0; i < Q; i++) { int f = dsuL.get(S[i], 2 * N - 1 - L[i]), s = dsuR.get(E[i], N + R[i]); int lx = dsuL.in[f], rx = dsuL.out[f] - 1; int ly = dsuR.in[s], ry = dsuR.out[s] - 1; //cout << lx << ' ' << rx << ' ' << ly << ' ' << ry << ' ' << tree.get(lx, ly, rx, ry) << '\n'; res[i] = (tree.get(lx, ly, rx, ry) > 0); } return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...