Submission #490620

#TimeUsernameProblemLanguageResultExecution timeMemory
490620dooompyRegions (IOI09_regions)C++11
100 / 100
3373 ms112868 KiB
#include "bits/stdc++.h" using namespace std; using ll = long long; #define MAXN 200005 #define MAXR 25005 #define INF (long long)1e18 #define BLOCK 450 int n, r, q; vector<int> region(MAXN); vector<vector<int>> adj(MAXN); int timer = 1; int tin[MAXN], tout[MAXN]; vector<vector<int>> sorted(MAXR); // sorted[r] stores the nodes from region r in sorted order of {tin, tout} vector<int> ind(MAXR); vector<vector<int>> par(BLOCK, vector<int>(MAXR)); vector<vector<int>> child(BLOCK, vector<int>(MAXR)); vector<int> largeRegions; void dfs(int i) { tin[i] = timer++; sorted[region[i]].push_back(i); for (auto a: adj[i]) { dfs(a); } tout[i] = timer - 1; } void genPar(int curr, int originalReg, int cnt) { par[ind[originalReg]][region[curr]] += cnt; cnt += (region[curr] == originalReg); for(auto child : adj[curr]) { genPar(child, originalReg, cnt); } } // Get answer for (a, b), sz[a] <= BLOCK, sz[b] > BLOCK int genChild(int curr, int originalReg) { int sub = (region[curr] == originalReg); for(auto child : adj[curr]) { sub += genChild(child, originalReg); } child[ind[originalReg]][region[curr]] += sub; return sub; } bool isAnc(int a, int b) { return tin[a] <= tin[b] && tout[b] <= tout[a]; } int getAns(int reg1, int reg2) { int l = 0, r = 0; int ans = 0; stack<int> st; while (l < sorted[reg1].size() || r < sorted[reg2].size()) { if ((l < sorted[reg1].size()) && (r == sorted[reg2].size() || tin[sorted[reg1][l]] < tin[sorted[reg2][r]])) { while (!st.empty() && !isAnc(st.top(), sorted[reg1][l])) { st.pop(); } st.push(sorted[reg1][l]); l++; } else { while (!st.empty() && !isAnc(st.top(), sorted[reg2][r])) { st.pop(); } ans += st.size(); r++; } } return ans; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("", "r", stdin); // freopen("", "w", stdout); int n, r, q; cin >> n >> r >> q; cin >> region[1]; for (int i = 2; i <= n; i++) { int s; cin >> s >> region[i]; adj[s].push_back(i); } dfs(1); int idx = 0; for (int i = 1; i <= r; i++) { if (sorted[i].size() > BLOCK) { largeRegions.push_back(i); ind[i] = idx++; } } for (auto a : largeRegions) { genPar(1, a, 0); genChild(1, a); } for (int i = 0; i < q; i++) { int a, b; cin >> a >> b; if (sorted[a].size() <= BLOCK && sorted[b].size() <= BLOCK) { cout << getAns(a, b) << endl; continue; } if (sorted[a].size() > BLOCK) { cout << par[ind[a]][b] << endl; } else { cout << child[ind[b]][a] << endl; } } }

Compilation message (stderr)

regions.cpp: In function 'int getAns(int, int)':
regions.cpp:65:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   65 |     while (l < sorted[reg1].size() || r < sorted[reg2].size()) {
      |            ~~^~~~~~~~~~~~~~~~~~~~~
regions.cpp:65:41: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   65 |     while (l < sorted[reg1].size() || r < sorted[reg2].size()) {
      |                                       ~~^~~~~~~~~~~~~~~~~~~~~
regions.cpp:66:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   66 |         if ((l < sorted[reg1].size()) && (r == sorted[reg2].size() || tin[sorted[reg1][l]] < tin[sorted[reg2][r]])) {
      |              ~~^~~~~~~~~~~~~~~~~~~~~
regions.cpp:66:45: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   66 |         if ((l < sorted[reg1].size()) && (r == sorted[reg2].size() || tin[sorted[reg1][l]] < tin[sorted[reg2][r]])) {
      |                                           ~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...