Advertisement
Guest User

Untitled

a guest
Dec 16th, 2014
808
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.19 KB | None | 0 0
  1. #include <algorithm>
  2. #include <string>
  3. #include <vector>
  4. #include <queue>
  5. #include <iostream>
  6. #include <cmath>
  7. #include <sstream>
  8. #include <map>
  9. #include <set>
  10. #include <numeric>
  11. #include <memory.h>
  12. #include <cstdio>
  13. #include <assert.h>
  14.  
  15. using namespace std;
  16.  
  17. #define pb push_back
  18. #define INF 1011111111
  19. #define FOR(i, a, b) for (int _n(b), i(a); i < _n; i++)
  20. #define rep(i, n) FOR(i, 0, n)
  21. #define CL(a, v) memset((a), (v), sizeof(a))
  22. #define mp make_pair
  23. #define X first
  24. #define Y second
  25. #define all(c) (c).begin(), (c).end()
  26. #define SORT(c) sort(all(c))
  27.  
  28. typedef long long ll;
  29. typedef vector<int> VI;
  30. typedef pair<int, int> pii;
  31.  
  32. /*** TEMPLATE CODE ENDS HERE */
  33.  
  34. const int maxn = 1e5 + 5;
  35. VI g[maxn];
  36. map<string, int> id;
  37. vector<string> name;
  38.  
  39. void go(int at, stringstream &ss) {
  40.   int to = -1;
  41.   for (string token; ss >> token;) {
  42.     if (token == ")") {
  43.       break;
  44.     } else if (token == "(") {
  45.       go(to, ss);
  46.     } else {
  47.       to = (int)id.size();
  48.       int nid = (int)id.size();
  49.       id[token] = nid;
  50.       name.push_back(token);
  51.       if (at >= 0) {
  52.         g[at].pb(to);
  53.         g[to].pb(at);
  54.       }
  55.     }
  56.   }
  57. }
  58.  
  59. // build tin, tout
  60. VI tin, tout;
  61. void dfs(int at, int from) {
  62.   static int tm = -1;
  63.   tin[at] = ++tm;
  64.   rep(i, (int)g[at].size()) {
  65.     int to = g[at][i];
  66.     if (to != from) {
  67.       dfs(to, at);
  68.     }
  69.   }
  70.   tout[at] = tm;
  71. }
  72.  
  73. void print(int at, int from) {
  74.   cout << name[at] << " " << tin[at] << " " << tout[at] << endl;
  75.   rep(i, (int)g[at].size()) {
  76.     int to = g[at][i];
  77.     if (to != from) {
  78.       print(to, at);
  79.     }
  80.   }
  81. }
  82.  
  83. // Persistent tree
  84.  
  85. struct Node {
  86.   int val;
  87.   int left, right;
  88.   Node(int val, int l, int r) : val(val), left(l), right(r) {}
  89. };
  90.  
  91. vector<Node> nodes;
  92.  
  93. int GetNewNode(int val, int left, int right) {
  94.   Node node(val, left, right);
  95.   nodes.push_back(node);
  96.   return (int)nodes.size() - 1;
  97. }
  98.  
  99. int GetVal(int pos) {
  100.   if (pos == -1) {
  101.     return 0;
  102.   }
  103.   return nodes[pos].val;
  104. }
  105.  
  106. int build(int l, int r) {
  107.   if (l == r) {
  108.     return GetNewNode(0, -1, -1);
  109.   }
  110.   int m = (l + r) / 2;
  111.   int left = build(l, m);
  112.   int right = build(m + 1, r);
  113.   int val = GetVal(left) + GetVal(right);
  114.  
  115.   return GetNewNode(val, left, right);
  116. }
  117.  
  118. int modify(int at, int l, int r, int idx, int val) {
  119.   assert(at != -1);
  120.   if (l == r) {
  121.     assert(idx == l);
  122.     return GetNewNode(nodes[at].val + val, -1, -1);
  123.   }
  124.   int m = (l + r) / 2;
  125.   int left = -2, right = -2;
  126.   if (idx <= m) {
  127.     left = modify(nodes[at].left, l, m, idx, val);
  128.     right = nodes[at].right;
  129.   } else {
  130.     left = nodes[at].left;
  131.     right = modify(nodes[at].right, m + 1, r, idx, val);
  132.   }
  133.   int s = GetVal(left) + GetVal(right);
  134.   return GetNewNode(s, left, right);
  135. }
  136.  
  137. int sum(int at, int l, int r, int ql, int qr) {
  138.   if (ql > qr || at == -1) {
  139.     return 0;
  140.   }
  141.   if (l == ql && r == qr) {
  142.     return GetVal(at);
  143.   }
  144.   int m = (l + r) / 2;
  145.   int s1 = sum(nodes[at].left, l, m, ql, min(qr, m));
  146.   int s2 = sum(nodes[at].right, m + 1, r, max(m + 1, ql), qr);
  147.   return s1 + s2;
  148. }
  149.  
  150. void PrintTree(int at) {
  151.   if (at == -1) {
  152.     return;
  153.   }
  154.   cout << "at: " << at << " val: " << nodes[at].val
  155.        << " left: " << nodes[at].left << " right: " << nodes[at].right << endl;
  156.   PrintTree(nodes[at].left);
  157.   PrintTree(nodes[at].right);
  158. }
  159.  
  160. int main() {
  161. #ifdef LOCAL_HOST
  162.   freopen("input.txt", "r", stdin);
  163. // freopen("output.txt","w",stdout);
  164. #endif
  165.  
  166.   ios_base::sync_with_stdio(false);
  167.  
  168.   int N, M, K;
  169.  
  170.   cin >> N;
  171.   {
  172.     string tree;
  173.     std::getline(std::cin, tree);
  174.     std::getline(std::cin, tree);
  175.     stringstream ss;
  176.     ss << tree;
  177.     ss << " )";
  178.     go(-1, ss);
  179.   }
  180.  
  181.   // Build Euler tour
  182.   tin.resize(id.size());
  183.   tout.resize(id.size());
  184.   dfs(0, -1);
  185.   // debug
  186.   // print(0, -1);
  187.   // Parse queries
  188.   cin >> M;
  189.   vector<pair<string, int> > msgs;
  190.   {
  191.     string line;
  192.     std::getline(std::cin, line);
  193.     rep(i, M) {
  194.       std::getline(std::cin, line);
  195.       string category = line.substr(0, line.find_first_of(':'));
  196.       string body = line.substr(line.find_first_of(':') + 2);
  197.       msgs.push_back(mp(body, id[category]));
  198.     }
  199.     SORT(msgs);
  200.   }
  201.  
  202.   int R = N - 1;
  203.   // put msgs to persistent tree
  204.   VI roots(msgs.size() + 1, -1);
  205.   roots[0] = build(0, R);
  206.   rep(i, (int)msgs.size()) {
  207.     roots[i + 1] = modify(roots[i], 0, R, msgs[i].Y, 1);
  208.   }
  209.  
  210.   cin >> K;
  211.   {
  212.     string line;
  213.     std::getline(std::cin, line);
  214.     rep(i, K) {
  215.       std::getline(std::cin, line);
  216.  
  217.       string category = line.substr(0, line.find_first_of(' '));
  218.       int cid = id[category];
  219.       string body = line.substr(line.find_first_of(' ') + 1);
  220.       int idx = int(lower_bound(all(msgs), mp(body, -1)) - msgs.begin());
  221.       int idx2 =
  222.           int(lower_bound(all(msgs), mp(body + char(200), -1)) - msgs.begin());
  223.       if (idx2 < idx) {
  224.         cout << 0 << endl;
  225.         continue;
  226.       }
  227.  
  228.       int cnt1 = sum(roots[idx2], 0, R, tin[cid], tout[cid]);
  229.       int cnt2 = sum(roots[idx], 0, R, tin[cid], tout[cid]);
  230.  
  231.       cout << cnt1 - cnt2 << endl;
  232.     }
  233.   }
  234.  
  235. #ifdef LOCAL_HOST
  236.   printf("TIME: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
  237. #endif
  238.  
  239.   return 0;
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement