zoukankan      html  css  js  c++  java
  • poj-3321-dfs序-线段树-邻接表

    思路:用邻接表存图,卡vector【这里被卡哭了QAQ】,用dfs遍历的顺序重新给节点编号,遍历时记录儿子数目。用dfs序建立线段树,change的时候单点更新,查询某子树上的苹果树即是查询该节点[i, i+childnum]这个区间的苹果数目,i指dfs序。

     总结:邻接表出边入边傻傻搞不清楚QAQ

    AC代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <cstring>
      5 #include <algorithm>
      6 using namespace std;
      7 #define maxn 200010
      8 #define lson l, m, rt<<1
      9 #define rson m+1, r, rt<<1|1
     10 struct node
     11 {
     12     int cnt, val, num;
     13 };
     14 int n, m;
     15 node arr[maxn];
     16 int u[maxn], v[maxn], next[maxn], first[maxn];
     17 bool vis[maxn];
     18 int sgt[maxn<<2];
     19 void init()
     20 {
     21     memset(vis, 0, sizeof(vis));
     22     for(int i = 0; i < n+10; i++)  first[i] = -1;
     23     int e = 0, i;
     24     for(i = 1; i < n; i++) {
     25         scanf("%d%d", &u[i], &v[i]);
     26         next[i] = first[u[i]];
     27         first[u[i]] = i;
     28         u[n-1+i] = v[i];
     29         v[n-1+i] = u[i];
     30         next[n-1+i] = first[u[n-1+i]];
     31         first[u[n-1+i]] = n-1+i;
     32     }
     33 }
     34 int dfs(int i, int &num)
     35 {//cout<<i<<" - "<<num<<endl;
     36     arr[i].val = 1;
     37     arr[i].cnt = 0;
     38     arr[i].num = num;
     39     vis[i] = 1;
     40     for(int j = first[i]; j != -1; j = next[j]) {
     41         if(!vis[v[j]]) { num++; arr[i].cnt += dfs(v[j], num);  }
     42     }
     43     return arr[i].cnt+1;
     44 }
     45 void push_up(int rt)
     46 {
     47     sgt[rt] = sgt[rt<<1] + sgt[rt<<1|1];
     48 }
     49 void build(int l, int r, int rt)
     50 {
     51     sgt[rt] = 1;
     52     if(l == r) return;
     53     int m = (r+l)>>1;
     54     build(lson);
     55     build(rson);
     56     push_up(rt);
     57 }
     58 void change(int l, int r, int rt, int pos)
     59 {
     60     if(l == r) {
     61         if(sgt[rt] == 1) sgt[rt] = 0;
     62         else sgt[rt] = 1;
     63         return;
     64     }
     65     int m = (r+l)>>1;
     66     if(pos <= m) change(lson, pos);
     67     else change(rson, pos);
     68     push_up(rt);
     69 }
     70 int query(int l, int r, int rt, int L, int R )
     71 {
     72     if(L <= l && r <= R) {
     73         return sgt[rt];
     74     }
     75     int res = 0;
     76     int m = (l+r)>>1;
     77     if(L <= m) res += query(lson, L, R);
     78     if(m < R) res += query(rson, L, R);
     79     return res;
     80 }
     81 void work()
     82 {
     83     if(n == 1) {
     84         int x = 1;
     85         scanf("%d", &m);
     86         char re; int k;
     87         while (m--) {
     88             getchar();
     89             scanf("%c%d", &re, &k);
     90             if(re == 'Q') {
     91                 printf("%d
    ", x);
     92             }
     93             else {
     94                 if(x == 0) x = 1; else x = 0;
     95             }
     96         }
     97     }else {
     98         init();
     99         int xxx = 1;
    100         dfs(1,xxx);
    101         build(1, n, 1);
    102         char re; int k;
    103         scanf("%d", &m);
    104         for (int i = 0; i < m; i++) {
    105             getchar();
    106             scanf("%c%d", &re, &k);
    107             if(re == 'C') {
    108                 change(1, n, 1, arr[k].num);
    109             }
    110             else {
    111                 int res = query(1, n, 1, arr[k].num, arr[k].num+arr[k].cnt);
    112                 printf("%d
    ", res);
    113             }
    114         }
    115     }
    116 }
    117 int main()
    118 {
    119     while(scanf("%d", &n) != EOF && n) work();
    120     return 0;
    121 }
    122 /*
    123 7
    124 1 3
    125 1 4
    126 3 5
    127 3 6
    128 4 2
    129 4 7
    130 11
    131 Q 2
    132 Q 2
    133 Q 1
    134 C 3
    135 Q 3
    136 C 3
    137 Q 3
    138 C 4
    139 Q 7
    140 Q 4
    141 Q 2
    142 
    143 */
    View Code
  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/3962849.html
Copyright © 2011-2022 走看看