Submission #945447

#TimeUsernameProblemLanguageResultExecution timeMemory
945447mc061Regions (IOI09_regions)C++17
40 / 100
8013 ms131072 KiB
#include <bits/stdc++.h> using namespace std; #ifdef ONLINE_JUDGE #include "debug.h" #else #pragma GCC optimize("O3") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #define dbg(...) 42 template<typename T>ostream&operator<<(ostream&os,vector<T>&vec){for(signed i=0;i+1<vec.size();++i){os<<vec[i]<<" ";}if(vec.size()>0)os<<vec.back();return os;} #endif const int N = 2e5 + 3; const int R = 25000; int n; int col[N]; int tin[N], tout[N]; vector<int> tree[N], tour; void build_tour(int v, int p=-1) { tour.push_back(v); tin[v] = tour.size() - 1; for (int u : tree[v]) if (u != p) { build_tour(u, v); } tout[v] = tour.size() - 1; } vector<int> seg[2 * N]; int get_node_count(const vector<int>& node, const int element) { return upper_bound(node.begin(), node.end(), element) - lower_bound(node.begin(), node.end(), element); } void combine(vector<int>& dest, const vector<int>& v1, const vector<int>& v2) { int p1 = 0, p2 = 0; while (p1 < v1.size() && p2 < v2.size()) { if (v1[p1] <= v2[p2]) dest.push_back(v1[p1++]); else dest.push_back(v2[p2++]); } while (p1 < v1.size()) dest.push_back(v1[p1++]); while (p2 < v2.size()) dest.push_back(v2[p2++]); } void build() { for (int i = 0; i < n; ++i) { seg[n + i].push_back(col[tour[i]]); } for (int i = n - 1; i > 0; --i) { combine(seg[i], seg[i << 1], seg[i << 1 | 1]); } } const int BLOCK = 200; int cnt[N / BLOCK][R] = {}; vector<int> comp[R]; int bigindex[N / BLOCK]; signed main(void) { cin.tie(0)->sync_with_stdio(false); int r, q; cin >> n >> r >> q; cin >> col[1]; --col[1]; comp[col[1]].push_back(1); for (int i = 2; i <= n; ++i) { int p; cin >> p >> col[i]; --col[i]; comp[col[i]].push_back(i); tree[p].push_back(i); tree[i].push_back(p); } build_tour(1); build(); int index = 0; for (int i = 0; i < r; ++i) { if (comp[i].size() >= BLOCK) { int cnt_now = 0; bigindex[i] = index; function<void(int, int)> dfs = [&] (int v, int p) -> void { if (col[v] == i) ++cnt_now; else cnt[index][col[v]] += cnt_now; for (int u : tree[v]) if (u != p) { dfs(u, v); } if (col[v] == i) --cnt_now; }; dfs(1, 1); ++index; } } while (q--) { int a, b; cin >> a >> b; --a, --b; if (comp[a].size() >= BLOCK) { cout << cnt[bigindex[a]][b] << endl; continue; } int ans = 0; for (int v : comp[a]) { int tl = tin[v] + n, tr = tout[v] + n + 1; for (; tl < tr; tl >>= 1, tr >>= 1) { if (tl&1) ans += get_node_count(seg[tl], b), ++tl; if (tr&1) --tr, ans += get_node_count(seg[tr], b); } } cout << ans << endl; } }

Compilation message (stderr)

regions.cpp: In function 'void combine(std::vector<int>&, const std::vector<int>&, const std::vector<int>&)':
regions.cpp:33:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   33 |  while (p1 < v1.size() && p2 < v2.size()) {
      |         ~~~^~~~~~~~~~~
regions.cpp:33:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   33 |  while (p1 < v1.size() && p2 < v2.size()) {
      |                           ~~~^~~~~~~~~~~
regions.cpp:37:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   37 |  while (p1 < v1.size()) dest.push_back(v1[p1++]);
      |         ~~~^~~~~~~~~~~
regions.cpp:38:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   38 |  while (p2 < v2.size()) dest.push_back(v2[p2++]);
      |         ~~~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...