Dang_Quan_10_Tin

F - TREEQUERY

Aug 15th, 2020
384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.95 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; i++)
  3. #define FORD(i, b, a) for (int i = (b), _a = (a); i >= _a; i--)
  4. #define REP(i, n) for (int i = 0, _n = (n); i < _n; i++)
  5. #define FORE(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); i++)
  6. #define ALL(v) (v).begin(), (v).end()
  7. #define IS_INF(x)   (std::isinf(x))
  8. #define IS_NAN(x)   (std::isnan(x))
  9. #define fi   first
  10. #define se   second
  11. #define MASK(i) (1LL << (i))
  12. #define BIT(x, i) (((x) >> (i)) & 1)
  13. #define div   ___div
  14. #define next   ___next
  15. #define prev   ___prev
  16. #define left   ___left
  17. #define right   ___right
  18. #define __builtin_popcount __builtin_popcountll
  19. using namespace std;
  20. template<class X, class Y>
  21.     bool minimize(X &x, const Y &y) {
  22.         X eps = 1e-9;
  23.         if (x > y + eps) {
  24.             x = y;
  25.             return true;
  26.         } else return false;
  27.     }
  28. template<class X, class Y>
  29.     bool maximize(X &x, const Y &y) {
  30.         X eps = 1e-9;
  31.         if (x + eps < y) {
  32.             x = y;
  33.             return true;
  34.         } else return false;
  35.     }
  36. template<class T>
  37.     T Abs(const T &x) {
  38.         return (x < 0 ? -x : x);
  39.     }
  40.  
  41. /* Author: Van Hanh Pham */
  42.  
  43. /** END OF TEMPLATE. DRINK A CUP OF TIGERSUGAR BEFORE READING MY CODE. **/
  44.  
  45. #define MAX_TOP   15
  46. const int INF = (int)21e8 + 7LL;
  47.  
  48. struct Top {
  49.     int value[MAX_TOP];
  50.  
  51.     Top() {
  52.         REP(i, MAX_TOP) value[i] = -INF;
  53.     }
  54.  
  55.     int& operator [] (int x) {
  56.         return value[x];
  57.     }
  58.     int operator [] (int x) const {
  59.         return value[x];
  60.     }
  61.  
  62.     void updateAll(int c) {
  63.         REP(i, MAX_TOP) {
  64.             if (value[i] > -INF) value[i] += c;
  65.             else break;
  66.         }
  67.     }
  68. };
  69.  
  70. Top merge(const Top &a, const Top &b, int need = MAX_TOP) {
  71.     Top res;
  72.     int x = 0, y = 0;
  73.     REP(i, need) res[i] = a[x] > b[y] ? a[x++] : b[y++];
  74.     return res;
  75. }
  76.  
  77. class SegmentTree {
  78. private:
  79.     vector<Top> top;
  80.     vector<int> lazy;
  81.     int n;
  82.  
  83.     void init(int i, int l, int r) {
  84.         if (l > r) return;
  85.         REP(j, min(r - l + 1, MAX_TOP)) top[i][j] = 0;
  86.         if (l == r) return;
  87.  
  88.         int m = (l + r) >> 1;
  89.         init(2 * i, l, m);
  90.         init(2 * i + 1, m + 1, r);
  91.     }
  92.  
  93.     void apply(int i, int c) {
  94.         top[i].updateAll(c);
  95.         lazy[i] += c;
  96.     }
  97.  
  98.     void pushDown(int i) {
  99.         REP(j, 2) apply(2 * i + j, lazy[i]);
  100.         lazy[i] = 0;
  101.     }
  102.  
  103.     void update(int i, int l, int r, int u, int v, int c) {
  104.         if (l > v || r < u || l > r || v < u) return;
  105.         if (u <= l && r <= v) return apply(i, c);
  106.  
  107.         pushDown(i);
  108.         int m = (l + r) >> 1;
  109.         update(2 * i, l, m, u, v, c);
  110.         update(2 * i + 1, m + 1, r, u, v, c);
  111.  
  112.         top[i] = merge(top[2 * i], top[2 * i + 1]);
  113.     }
  114.  
  115.     Top getPos(int i, int l, int r, int u, int v, int pos) {
  116.         if (l > v || r < u || l > r || v < u) return Top();
  117.         if (u <= l && r <= v) return top[i];
  118.  
  119.         pushDown(i);
  120.         int m = (l + r) >> 1;
  121.         Top L = getPos(2 * i, l, m, u, v, pos);
  122.         Top R = getPos(2 * i + 1, m + 1, r, u, v, pos);
  123.         return merge(L, R, pos);
  124.     }
  125.  
  126. public:
  127.     SegmentTree(int n = 0) {
  128.         this->n = n;
  129.         if (n > 0) {
  130.             top.assign(4 * n + 7, Top());
  131.             lazy.assign(4 * n + 7, 0);
  132.             init(1, 1, n);
  133.         }
  134.     }
  135.  
  136.     void update(int l, int r, int c) {
  137.         update(1, 1, n, l, r, c);
  138.     }
  139.  
  140.     int getValue(int pos) {
  141.         int i = 1, l = 1, r = n;
  142.         while (true) {
  143.             if (l == r) return top[i][0];
  144.             pushDown(i);
  145.             int m = (l + r) >> 1;
  146.             if (pos > m) {
  147.                 i = 2 * i + 1; l = m + 1;
  148.             } else {
  149.                 i = 2 * i; r = m;
  150.             }
  151.         }
  152.     }
  153.  
  154.     Top getPos(int l, int r, int pos) {
  155.         return getPos(1, 1, n, l, r, pos);
  156.     }
  157. };
  158.  
  159. #define MAX   300300
  160. int numNode, numQuery;
  161. vector<int> children[MAX];
  162. int parity[MAX], treeSize[MAX];
  163. int parityCount[2], sta[2][MAX], fin[2][MAX];
  164. SegmentTree myit[2];
  165.  
  166. void loadTree(void) {
  167.     int subtask; scanf("%d%d", &subtask, &numNode);
  168.     FOR(i, 2, numNode) {
  169.         int p; scanf("%d", &p);
  170.         children[p].push_back(i);
  171.     }
  172. }
  173.  
  174. void dfs(int u, int high) {
  175.     REP(i, 2) sta[i][u] = parityCount[i] + 1;
  176.     parity[u] = high;
  177.     parityCount[high]++;
  178.  
  179.     treeSize[u] = 1;
  180.     FORE(it, children[u]) {
  181.         dfs(*it, high ^ 1);
  182.         treeSize[u] += treeSize[*it];
  183.     }
  184.  
  185.     REP(i, 2) fin[i][u] = parityCount[i];
  186. }
  187.  
  188. void update(int node, int delta) {
  189.     REP(i, 2) myit[i].update(sta[i][node], fin[i][node], i == parity[node] ? delta : -delta);
  190. }
  191.  
  192. int getValue(int node) {
  193.     return myit[parity[node]].getValue(sta[parity[node]][node]);
  194. }
  195.  
  196. int getPos(int node, int pos) {
  197.     if (treeSize[node] < pos) return 0;
  198.  
  199.     Top top[2];
  200.     REP(i, 2) top[i] = myit[i].getPos(sta[i][node], fin[i][node], pos);
  201.     return merge(top[0], top[1], pos)[pos - 1];
  202. }
  203.  
  204. void process(void) {
  205.     dfs(1, 0);
  206.     REP(i, 2) myit[i] = SegmentTree(parityCount[i]);
  207.  
  208.     char input[6];
  209.     int node;
  210.     scanf("%d", &numQuery);
  211.     REP(love, numQuery) {
  212.         scanf("%s", input);
  213.         scanf("%d", &node);
  214.  
  215.         switch (input[0]) {
  216.         case 'a':
  217.             int delta; scanf("%d", &delta);
  218.             update(node, delta);
  219.             break;
  220.  
  221.         case 'g':
  222.             printf("%d ", getValue(node));
  223.             break;
  224.  
  225.         case 'p':
  226.             int pos; scanf("%d", &pos);
  227.             printf("%d ", getPos(node, pos));
  228.             break;
  229.  
  230.         default:
  231.             cout << "Strange query" << endl;
  232.             assert(false);
  233.         }
  234.     }
  235.  
  236.     printf("\n");
  237. }
  238.  
  239. int main(void) {
  240. #ifdef ONLINE_JUDGE
  241.     freopen("query.inp", "r", stdin);
  242.     freopen("query.out", "w", stdout);
  243. #endif // ONLINE_JUDGE
  244.  
  245.     loadTree();
  246.     process();
  247.     return 0;
  248. }
  249.  
  250. /*** BUBBLE TEA IS GREAT. MY CODE IS AMAZING :D ***/
Advertisement
Add Comment
Please, Sign In to add comment