Submission #649259

#TimeUsernameProblemLanguageResultExecution timeMemory
649259vladutpieleRegions (IOI09_regions)C++17
0 / 100
1882 ms33204 KiB
#include <bits/stdc++.h> using namespace std; const int nmax = 200000; const int block = 1000; int n, r, q; int region[nmax + 5], cntRegion[nmax + 5]; int bigRegion[nmax + 5], cntBigRegion, bigIdx[nmax + 5]; int smallRegion[nmax + 5], cntSmallRegion, smallIdx[nmax + 5]; int cntAbove[nmax + 5], sol[205][25005], sumePartiale[nmax + 5]; int precalc[205][25005]; int cntTimp; pair<int, int> timp[nmax + 5]; vector<int> nodesFromRegion[nmax + 5]; vector<int> g[nmax + 5]; void dfs(int fiu, int tata) { timp[fiu].first = ++cntTimp; /// cntAbove[i] -> numarul de noduri de regiunea i(care este o regiune de tip BIG), care sunt stramosi ai nodului curent if(bigIdx[region[fiu]] != 0) { cntAbove[bigIdx[region[fiu]]] ++; } for(int i = 1; i <= cntBigRegion; i ++) { sol[bigIdx[bigRegion[i]]][region[fiu]] += cntAbove[bigIdx[region[fiu]]]; } for(auto it : g[fiu]) { if(it == tata) { continue; } dfs(it, fiu); } if(bigIdx[region[fiu]] != 0) { cntAbove[bigIdx[region[fiu]]] ++; } timp[fiu].second = cntTimp; } int main() { cin >> n >> r >> q; cin >> region[1]; cntRegion[region[1]] ++; for(int i = 2; i <= n; i ++) { int p; cin >> p >> region[i]; g[p].push_back(i); g[i].push_back(p); cntRegion[region[i]] ++; nodesFromRegion[region[i]].push_back(i); } for(int i = 1; i <= r; i ++) { if(cntRegion[i] >= block) { bigRegion[++cntBigRegion] = i; bigIdx[i] = cntBigRegion; } else { smallRegion[++cntSmallRegion] = i; smallIdx[i] = cntSmallRegion; } } /// in dfs calculez pentru tipurile 1 si 2, cand regiunea de sus este de tip BIG dfs(1, 0); /// imi propun sa calculez pentru tipul 3, cand regiunea de jos este de tip BIG, iar regiunea de sus este de tip SMALL for(int i = 1; i <= r; i ++) { if(bigIdx[i] == 0) { continue; } for(auto it : nodesFromRegion[i]) { sumePartiale[timp[it].first] ++; } for(int j = 1; j <= n; j ++) { sumePartiale[j] += sumePartiale[j - 1]; } for(int j = 1; j <= cntSmallRegion; j ++) { for(auto it : nodesFromRegion[smallRegion[i]]) { precalc[bigIdx[i]][j] += 1LL * (sumePartiale[timp[it].second] - sumePartiale[timp[it].first] - 1); } } for(int j = 1; j <= n; j ++) { sumePartiale[j] = 0; } } while(q--) { int a, b; cin >> a >> b; if(bigIdx[a] != 0) { /// cand regiunea de sus e de tip BIG cout << sol[bigIdx[a]][b] << '\n'; } else { if(bigIdx[b] != 0) { /// cand regiunea de jos e BIG, dar cea de sus e SMALL cout << precalc[bigIdx[b]][smallIdx[a]] << '\n'; } else { cout << 0 << '\n'; } } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...