Submission #394211

#TimeUsernameProblemLanguageResultExecution timeMemory
394211BertedRegions (IOI09_regions)C++14
95 / 100
5093 ms131076 KiB
#include <iostream> #include <vector> #include <algorithm> #define ll long long #define pii pair<int, int> #define fst first #define snd second using namespace std; const int SZ = 750; int N, K, Q, A[200001], L[200001], R[200001], ord[200001], ti = 0; int num[25001], tp[SZ], cnt[SZ][25001]; vector<int> adj[200001], idx[25001]; pii seg[19][200001]; vector<pii> temp; void DFS(int u, int p) { for (int i = 0; i < SZ && i < K; i++) {cnt[i][A[u]] += tp[i];} if (num[A[u]] < SZ) {tp[num[A[u]]]++;} L[u] = R[u] = ti; ord[ti++] = A[u]; for (const int &v : adj[u]) {DFS(v, u); R[u] = R[v];} if (num[A[u]] < SZ) {tp[num[A[u]]]--;} //cerr << "DFS: " << u << ", " << p << " - " << L[u] << ", " << R[u] << "\n"; } void build(int idx, int L, int R, int lvl, bool b) { if (L <= R) { for (int i = L; i <= R; i++) seg[lvl][i] = make_pair(ord[i], i); if (b) sort(seg[lvl] + L, seg[lvl] + R + 1); else sort(seg[lvl] + L, seg[lvl] + R + 1, greater<pii>()); if (L < R) { int M = L + R >> 1; build(2 * idx, L, M, lvl + 1, 0); build(2 * idx + 1, M + 1, R, lvl + 1, 1); } } } int query(int idx, int L, int R, int lvl, bool b, int l, int r, int v) { l = max(L, l); r = min(R, r); if (l <= r) { //cerr << "CALL: " << idx << " " << L << " " << R << " " << b << " " << l << " " << r << " " << v << "\n"; if (b && l == L) { auto itR = upper_bound(seg[lvl] + L, seg[lvl] + R + 1, make_pair(v, r)); auto itL = lower_bound(seg[lvl] + L, seg[lvl] + R + 1, make_pair(v, l)); //cerr << "ANS1: " << L - seg[idx].begin() << " " << R - seg[idx].begin() << "\n"; return itR - itL; } else if (!b && r == R) { auto itR = upper_bound(seg[lvl] + L, seg[lvl] + R + 1, make_pair(v, l), greater<pii>()); auto itL = lower_bound(seg[lvl] + L, seg[lvl] + R + 1, make_pair(v, r), greater<pii>()); //cerr << "ANS0: " << L - seg[idx].begin() << " " << R - seg[idx].begin() << "\n"; return itR - itL; } else { int M = L + R >> 1; return query(2 * idx, L, M, lvl + 1, 0, l, r, v) + query(2 * idx + 1, M + 1, R, lvl + 1, 1, l, r, v); } } return 0; } int main() { ios :: sync_with_stdio(0); cin.tie(0); cin >> N >> K >> Q; for (int i = 0; i < N; i++) { if (i) {int p; cin >> p; adj[p - 1].push_back(i);} cin >> A[i]; A[i]--; idx[A[i]].push_back(i); } for (int i = 0; i < K; i++) {temp.push_back({idx[i].size(), i}); num[i] = -1;} sort(temp.begin(), temp.end(), greater<pii>()); for (int i = 0; i < K; i++) {num[temp[i].snd] = i;} temp.clear(); DFS(0, -1); for (int i = 0; i < N; i++) adj[i].clear(); //for (int i = 0; i < N; i++) cerr << ord[i] << " "; cerr << "\n"; build(1, 0, N - 1, 0, 1); for (int i = 0; i < Q; i++) { int a, b; cin >> a >> b; a--; b--; if (num[a] < SZ) cout << cnt[num[a]][b] << endl; else { int res = 0; for (const int &u : idx[a]) res += query(1, 0, N - 1, 0, 1, L[u] + 1, R[u], b); cout << res << endl; } } return 0; }

Compilation message (stderr)

regions.cpp: In function 'void build(int, int, int, int, bool)':
regions.cpp:44:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   44 |    int M = L + R >> 1;
      |            ~~^~~
regions.cpp: In function 'int query(int, int, int, int, bool, int, int, int)':
regions.cpp:74:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   74 |    int M = L + R >> 1;
      |            ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...