Submission #283294

#TimeUsernameProblemLanguageResultExecution timeMemory
283294milleniumEeeeWerewolf (IOI18_werewolf)C++14
0 / 100
1752 ms76152 KiB
#include "werewolf.h" #include <bits/stdc++.h> #include <random> #include <chrono> #include <array> using namespace std; mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); #define szof(s) (int)s.size() #define all(s) s.begin(), s.end() #define prev prev123 #define pii pair<int, int> #define fr first #define sc second typedef vector<int> vi; const int MAXN = (int)2e5 + 5; const int MAXM = (int)4e5 + 5; const int MAXQ = (int)2e5 + 5; vector <int> g[MAXN]; int N, M, Q; struct Query { int s, e, l, r; Query (int s_, int e_, int l_, int r_) { s = s_, e = e_, l = l_, r = r_; } Query () { } }query[MAXQ]; struct Small_Solve { vector <int> ans; bool need() { return (N <= 3000 && M <= 6000 && Q <= 3000); } void solve() { ans.resize(Q, 0); vector <int> used[3]; used[1].resize(N, 0); used[2].resize(N, 0); int cnt = 0; for (int i = 0; i < Q; i++) { cnt++; queue <int> q[3]; if (query[i].s >= query[i].l) { q[1].push(query[i].s); } if (query[i].e <= query[i].r) { q[2].push(query[i].e); } while (!q[1].empty()) { int v = q[1].front(); q[1].pop(); if (used[1][v] == cnt) { continue; } used[1][v] = cnt; for (int to : g[v]) { if (to >= query[i].l) { q[1].push(to); } } } while (!q[2].empty()) { int v = q[2].front(); q[2].pop(); if (used[2][v] == cnt) { continue; } used[2][v] = cnt; for (int to : g[v]) { if (to <= query[i].r) { q[2].push(to); } } } int found = 0; for (int v = 0; v < N; v++) { found |= (used[1][v] == cnt && used[2][v] == cnt); } ans[i] = found; } } }subtask12; struct Line_Solve { int start = -1, finish = -1; pii table[20][(int)2e5 + 5]; int pows[20]; vector <bool> used; vector <int> pos; vector <int> convert; vector <int> ans; Line_Solve() { pows[0] = 1; for (int i = 0; i < 20; i++) { pows[i] = pows[i - 1] * 2; } } bool need() { if (M != N - 1) { return false; } for (int i = 0; i < N; i++) { if (szof(g[i]) == 1) { if (start == -1) { start = i; } else { finish = i; } } } return true; } pii merge(pii &a, pii &b) { return {min(a.fr, b.fr), max(a.sc, b.sc)}; } bool in(int l1, int r1, int l2, int r2) { // l1...r1 in l2...r2 return (l2 <= l1 && r1 <= r2); } pii get(int l, int r) { if (l == r) { return table[0][l]; } else { int pw = log2(r - l + 1); return merge(table[pw][l], table[pw][r - pows[pw] + 1]); } }; pii get_segment(int our_pos, int L, int R) { pii segment = {-1, -1}; int l = -1, r = our_pos; while (r - l > 1) { int mid = (l + r) >> 1; pii pr = get(mid, our_pos); if (in(pr.fr, pr.sc, L, R)) { r = mid; } else { l = mid; } } segment.fr = r; l = our_pos, r = N; while (r - l > 1) { int mid = (l + r) >> 1; pii pr = get(our_pos, mid); if (in(pr.fr, pr.sc, L, R)) { l = mid; } else { r = mid; } } segment.sc = l; return segment; } void dfs(int v, int id) { used[v] = 1; pos[v] = id; convert[id] = v; for (int to : g[v]) { if (!used[to]) { dfs(to, id + 1); } } } void solve() { used.resize(N, false); pos.resize(N); convert.resize(N); ans.resize(Q); dfs(start, 0); for (int pw = 0; pw < 20; pw++) { for (int i = 0; i < N; i++) { if (pw == 0) { table[pw][i] = {convert[i], convert[i]}; } else if (i + pows[i] - 1 < N) { table[pw][i] = merge(table[pw - 1][i], table[pw - 1][i + pows[pw - 1]]); } } } for (int i = 0; i < Q; i++) { if ((query[i].s >= query[i].l && query[i].e <= query[i].r) == false) { ans[i] = 0; continue; } pii segment[3]; segment[1] = get_segment(query[i].s, query[i].l, N - 1); segment[2] = get_segment(query[i].e, 0, query[i].r); ans[i] = !(segment[1].fr > segment[2].sc || segment[2].fr > segment[1].sc); } } }subtask3; vi check_validity(int NN, vi X, vi Y, vi S, vi E, vi L, vi R) { N = NN; M = szof(X); Q = szof(S); for (int i = 0; i < NN; i++) { g[i].clear(); } for (int i = 0; i < M; i++) { g[X[i]].push_back(Y[i]); g[Y[i]].push_back(X[i]); } for (int i = 0; i < Q; i++) { query[i] = Query(S[i], E[i], L[i], R[i]); } if (subtask3.need()) { subtask3.solve(); return subtask3.ans; } else { return {}; } } //int gen(int l, int r) { //long long int x = rnd(); //x = abs(x); //return l + (x % (r - l + 1)); //} //int pr[1000]; //int findp(int v); //void unite(int u, int v); //void not_line(); //signed main() { //while (1) { //int n = gen(2, 6); //vector <int> vec; //for (int i = 0; i < n; i++) { //vec.push_back(i); //} //shuffle(vec.begin(), vec.end(), rnd); //int NN, QQ; //NN = n, QQ = gen(1, 5); //vector <int> X(n - 1), Y(n - 1), S(QQ), E(QQ), L(QQ), R(QQ); //for (int i = 0; i < n; i++) { //if (i + 1 < n) { //X[i] = vec[i]; //Y[i] = vec[i + 1]; //} //} //for (int i = 0; i < QQ; i++) { //do { //S[i] = gen(0, NN - 1), E[i] = gen(0, NN - 1); //} //while (S[i] == E[i]); //L[i] = gen(0, NN - 1); //R[i] = gen(0, NN - 1); //} //vector <int> ans = check_validity(NN, X, Y, S, E, L, R); //} //} /////////////////////////////////////////////// //int findp(int v) { //if (v == pr[v]) { //return v; //} //return pr[v] = findp(pr[v]); //} //void unite(int x, int y) { //x = findp(x); //y = findp(y); //if (x == y) { //return; //} //pr[x] = y; //} //void not_line() { //while (1) { //vector <vector<int>> put; //int NN = gen(1, 5); //int MM = gen(NN - 1, NN * (NN - 1) / 2); //int QQ = gen(1, 1); //vector<int> X(MM), Y(MM), S(QQ), E(QQ), L(QQ), R(QQ); //for (int i = 0; i < NN; i++) { //pr[i] = i; //} //set <pii> edges; //int xod = 0; //int cnt = 0; //while (cnt < NN - 1) { //int x = -1, y = -1; //while (x == y || findp(x) == findp(y)) { //x = gen(0, NN - 1); //y = gen(0, NN - 1); //} //unite(x, y); //X[xod] = x, Y[xod] = y; //edges.insert({x, y}); //edges.insert({y, x}); //xod++; //cnt++; //put.push_back({x, y}); //} //for (int i = NN; i <= MM; i++) { //int x = -1, y = -1; //while (x == y || edges.find({x, y}) != edges.end() || edges.find({y, x}) != edges.end()) { //x = gen(0, NN - 1); //y = gen(0, NN - 1); //} //X[xod] = x; //Y[xod] = y; //edges.insert({x, y}); //edges.insert({y, x}); //put.push_back({x, y}); //} //for (int i = 0; i < QQ; ++i) { //S[i] = gen(0, NN - 1); //do { //E[i] = gen(0, NN - 1); //} while (E[i] == S[i]); //L[i] = gen(0, NN - 1); //R[i] = gen(0, NN - 1); //put.push_back({S[i], E[i], L[i], R[i]}); //} //vector<int> A = check_validity(NN, X, Y, S, E, L, R); //puts("finish"); //} //} /* 4 0 2 2 1 1 3 */ /* 5 4 1 2 0 0 4 4 1 1 3 0 1 0 4 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...