Submission #252356

#TimeUsernameProblemLanguageResultExecution timeMemory
252356IgorISynchronization (JOI13_synchronization)C++17
0 / 100
4385 ms22724 KiB
const int LG = 21; const int N = 200005; const long long MOD = 1e9 + 7; const long long INF = 1e9; const long long INFLL = 1e18; #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<vector<int> > vvi; typedef vector<ll> vll; #define forn(i, n) for (int (i) = 0; (i) != (n); (i)++) #define all(v) (v).begin(), (v).end() #define rall(v) (v).rbegin(), (v).rend() #define popcount(x) __builtin_popcount(x) #define popcountll(x) __builtin_popcountll(x) #define fi first #define se second #define re return #define pb push_back #define uniq(x) sort(all(x)); (x).resize(unique(all(x)) - (x).begin()) #ifdef LOCAL #define dbg(x) cerr << __LINE__ << " " << #x << " " << x << endl #define ln cerr << __LINE__ << endl #else #define dbg(x) void(0) #define ln void(0) #endif // LOCAL int n, m, q; int Get(int pos, vector<int> &tree, int L = 0, int R = n, int V = 0) { if (tree[V] != -1) { return tree[V]; } int M = (L + R) / 2; if (pos < M) return Get(pos, tree, L, M, 2 * V + 1); else return Get(pos, tree, M, R, 2 * V + 2); } void Set(int l, int r, int x, vector<int> &tree, int L = 0, int R = n, int V = 0) { if (r <= L || R <= l) { return; } if (l <= L && R <= r) { tree[V] = x; return; } int M = (L + R) / 2; if (tree[V] != -1) tree[2 * V + 1] = tree[V]; if (tree[V] != -1) tree[2 * V + 2] = tree[V]; tree[V] = -1; Set(l, r, x, tree, L, M, 2 * V + 1); Set(l, r, x, tree, M, R, 2 * V + 2); } int Get2(int pos, vector<int> &tree, int L = 0, int R = n - 1, int V = 0) { if (L + 1 == R) { return tree[V]; } int M = (L + R) / 2; if (pos < M) return Get2(pos, tree, L, M, 2 * V + 1); else return Get2(pos, tree, M, R, 2 * V + 2); } void Set2(int pos, int x, vector<int> &tree, int L = 0, int R = n - 1, int V = 0) { if (L + 1 == R) { tree[V] = x; return; } int M = (L + R) / 2; if (pos < M) Set2(pos, x, tree, L, M, 2 * V + 1); else Set2(pos, x, tree, M, R, 2 * V + 2); tree[V] = tree[2 * V + 1] + tree[2 * V + 2]; } int FirstZero(int l, int r, vector<int> &tree, int L = 0, int R = n - 1, int V = 0) { if (r <= L || R <= l) { return r; } if (l <= L && R <= r) { if (tree[V] == R - L) return r; if (L + 1 == R) return L; int M = (L + R) / 2; if (tree[2 * V + 1] == M - L) return FirstZero(l, r, tree, M, R, 2 * V + 2); else return FirstZero(l, r, tree, L, M, 2 * V + 1); } if (tree[V] == R - L) return r; int M = (L + R) / 2; int a = FirstZero(l, r, tree, L, M, 2 * V + 1); if (a != r) return a; return FirstZero(l, r, tree, M, R, 2 * V + 2); } int LastZero(int l, int r, vector<int> &tree, int L = 0, int R = n - 1, int V = 0) { if (r <= L || R <= l) { return l - 1; } if (l <= L && R <= r) { if (tree[V] == R - L) return l - 1; if (L + 1 == R) return L; int M = (L + R) / 2; if (tree[2 * V + 2] == R - M) return LastZero(l, r, tree, L, M, 2 * V + 1); else return LastZero(l, r, tree, M, R, 2 * V + 2); } if (tree[V] == R - L) return r; int M = (L + R) / 2; int a = LastZero(l, r, tree, M, R, 2 * V + 2); if (a != l - 1) return a; return LastZero(l, r, tree, L, M, 2 * V + 1);; } void solve_line() { vector<int> le(4 * n, -1), ri(4 * n, -1); for (int i = 0; i < n; i++) { Set(i, i + 1, i, le); Set(i, i + 1, i, ri); } vector<int> act(4 * n, 0); for (int i = 0; i < m; i++) { int z; cin >> z; z--; if (Get2(z, act)) { Set2(z, 0, act); continue; } Set2(z, 1, act); int r = FirstZero(z, n - 1, act); assert(r == n - 1 || Get2(r, act) == 0); int l = LastZero(0, z, act); assert(l == -1 || Get2(l, act) == 0); l++; Set(l, r + 1, Get(z + 1, ri), ri); Set(l, r + 1, Get(z, le), le); } vector<int> ans(n); for (int i = 0; i < n; i++) { ans[i] = Get(i, ri) - Get(i, le) + 1; } for (int i = 0; i < q; i++) { int v; cin >> v; v--; cout << ans[v] << "\n"; } } int dfs(int v, int p, int t, vvi &graph, vi &x, vi &y, vector<vector<pii> > &act) { int res = 1; for (auto i : graph[v]) { int u = x[i] + y[i] - v; if (u != p) { int L = -1, R = act[i].size(); while (L + 1 < R) { int M = (L + R) / 2; if (act[i][M].first <= t) L = M; else R = M; } if (L == -1) continue; int T = min(act[i][L].second, t); res += dfs(u, v, T, graph, x, y, act); } } return res; } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> q; vector<int> x(n - 1), y(n - 1); vector<vector<int> > graph(n); int line = 1; for (int i = 0; i < n - 1; i++) { cin >> x[i] >> y[i]; x[i]--, y[i]--; if (x[i] != i || y[i] != i + 1) line = 0; graph[x[i]].push_back(i); graph[y[i]].push_back(i); } if (line) { solve_line(); return 0; } vector<int> fr(n - 1, -1); vector<vector<pii> > act(n - 1); for (int i = 0; i < m; i++) { int z; cin >> z; z--; if (fr[z] == -1) { fr[z] = i; } else { act[z].push_back({fr[z], i}); fr[z] = -1; } } for (int i = 0; i < n - 1; i++) { if (fr[i] != -1) { act[i].push_back({fr[i], m}); } } for (int i = 0; i < q; i++) { int v; cin >> v; v--; cout << dfs(v, v, m, graph, x, y, act) << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...