Advertisement
trungore10

coltree_AnhVuong

Nov 20th, 2018
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.54 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. void Read(int &val) {
  5.     val = 0; char c;
  6.     do { c = getchar(); } while (!isdigit(c));
  7.     while (isdigit(c)) { val = val * 10 + c - '0'; c = getchar(); }
  8. }
  9. void Write(int val) {
  10.     if (val < 10) putchar('0' + val);
  11.     else Write(val/10), putchar('0' + val%10);
  12. }
  13.  
  14. const int N = 2e5 + 4, SQ = 504, COLOR = 25004;
  15. int n, numColor, Q, color[N];
  16. vector<int> adj[N];
  17.  
  18. int numVer[N], Map[N];
  19. vector<int> lsVer[COLOR], Small, Big;
  20.  
  21. int Big_dad[SQ][COLOR], Big_son[SQ][COLOR];
  22. int Count[N], cnt;
  23.  
  24. void DFS(int par, int u, int col) {
  25.     Count[u] = (color[u] == col);
  26.     cnt += (color[u] == col);
  27.    
  28.     for (int v : adj[u]) if (v != par) {
  29.         DFS(u, v, col);
  30.         Count[u] += Count[v];
  31.     }
  32.  
  33.     Big_son[Map[col]][color[u]] += Count[u];
  34.     Big_dad[Map[col]][color[u]] += cnt;
  35.  
  36.     cnt -= (color[u] == col);
  37. }
  38.  
  39. void prepare_BigCase() {
  40.     for (int col : Big) {
  41.         for (int i = 1; i <= numColor; ++i) Count[i] = 0; cnt = 0;
  42.         DFS(0, 1, col);
  43.     }
  44. }
  45.  
  46. int numET, Begin[N], End[N], Match[N];
  47.  
  48. void Build_ETT(int par, int u) {
  49.     Begin[u] = ++numET; Match[numET] = u;
  50.     for (int v : adj[u]) if (v != par) Build_ETT(u, v);
  51.     End[u] = numET;
  52. }
  53.  
  54. vector<int> L[COLOR], R[COLOR];
  55.  
  56. void prepare_SmallCase() {
  57.     Build_ETT(0, 1);
  58.  
  59.     for (int col : Small) {
  60.         sort(lsVer[col].begin(), lsVer[col].end(), [] (int &a, int &b) {
  61.             return Begin[a] < Begin[b];
  62.         });
  63.        
  64.         for (int ver : lsVer[col]) L[col].push_back(Begin[ver]), R[col].push_back(End[ver]);
  65.         R[col].resize(unique(R[col].begin(), R[col].end()) - R[col].begin());
  66.     }
  67. }
  68.  
  69. vector<int> V, tmp;
  70. int partial[N], pos[N];
  71.  
  72. int process_Small(int u, int v) {
  73.     /// use Merge_sort
  74.     tmp.clear(); V.clear();
  75.  
  76.     tmp.resize(L[u].size()+R[u].size());
  77.     V.resize(L[u].size() + L[v].size() + R[u].size());
  78.  
  79.     merge(L[u].begin(), L[u].end(), R[u].begin(), R[u].end(), tmp.begin());
  80.     merge(L[v].begin(), L[v].end(), tmp.begin(), tmp.end(), V.begin());
  81.  
  82.     V.resize(unique(V.begin(), V.end())- V.begin());
  83.  
  84.     for (int i = 0; i < (int) V.size(); ++i) {
  85.         pos[V[i]] = i;
  86.         partial[i] = (i == 0) ? 0 : partial[i-1];
  87.         if (color[ Match[V[i]] ] == v) partial[i]++;
  88.     }
  89.  
  90.     int res = 0;
  91.     for (int ver : lsVer[u]) {
  92.         int l = pos[Begin[ver]], r = pos[End[ver]];
  93.         res += (l == 0) ? partial[r] : partial[r] - partial[l-1];
  94.     }
  95.     return res;
  96. }
  97.  
  98. void Answer_Query() {
  99.     int u, v, res;
  100.     while (Q--) {
  101.         Read(u); Read(v); res = 0;
  102.        
  103.         if (numVer[u] > sqrt(n)) res = Big_dad[Map[u]][v];
  104.         else if (numVer[v] > sqrt(n)) res = Big_son[Map[v]][u];
  105.         else res = process_Small(u, v);
  106.  
  107.         Write(res); putchar('\n');
  108.     }
  109. }
  110.  
  111. void sol() {
  112.     for (int u = 1; u <= n; ++u) {
  113.         numVer[color[u]]++;
  114.         lsVer[color[u]].push_back(u);
  115.     }
  116.  
  117.     for (int i = 1; i <= numColor; ++i) {
  118.         if (numVer[i] > sqrt(n)) Big.push_back(i), Map[i] = Big.size()-1;
  119.         else Small.push_back(i), Map[i] = Small.size()-1;
  120.     }
  121.  
  122.     prepare_BigCase();
  123.     prepare_SmallCase();
  124.  
  125.     Answer_Query();
  126. }
  127.  
  128. int main() {
  129.     if (fopen("input.txt", "r")) {
  130.         freopen("input.txt", "r", stdin);
  131.     }
  132.     else {  
  133.         freopen("coltree.in", "r", stdin);
  134.         freopen("coltree.out", "w", stdout);
  135.     }
  136.  
  137.     Read(n); Read(numColor); Read(Q);
  138.     Read(color[1]);
  139.     int v;
  140.     for (int u = 2; u <= n; ++u) {
  141.         Read(v); Read(color[u]);
  142.         adj[u].push_back(v); adj[v].push_back(u);
  143.     }
  144.  
  145.     sol();
  146.  
  147.     return 0;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement