zoukankan      html  css  js  c++  java
  • BZOJ 4551: [Tjoi2016&Heoi2016]树

    4551: [Tjoi2016&Heoi2016]树

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 941  Solved: 485
    [Submit][Status][Discuss]

    Description

    在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
    两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
    结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
    先)你能帮帮他吗?

    Input

    输入第一行两个正整数N和Q分别表示节点个数和操作次数接下来N-1行,每行两个正整数u,v(1≤u,v≤n)表示u到v
    有一条有向边接下来Q行,形如“opernum”oper为“C”时表示这是一个标记操作,oper为“Q”时表示这是一个询
    问操作对于每次询问操作,1 ≤ N, Q ≤ 100000。

    Output

    输出一个正整数,表示结果

    Sample Input

    5 5
    1 2
    1 3
    2 4
    2 5
    Q 2
    C 2
    Q 2
    Q 5
    Q 3

    Sample Output

    1
    2
    2
    1

    HINT

     新加数据9组(By HFLSyzx ),未重测--2016.8.2

    Source

     
    [Submit][Status][Discuss]

    离线,用并查集维护答案指向。

     1 #include <cstdio>
     2 
     3 const int mxn = 200005;
     4 
     5 int n, m;
     6 
     7 int tot;
     8 int hd[mxn];
     9 int to[mxn];
    10 int nt[mxn];
    11 
    12 inline void add(int x, int y)
    13 {
    14     nt[++tot] = hd[x], to[tot] = y, hd[x] = tot;
    15     nt[++tot] = hd[y], to[tot] = x, hd[y] = tot;
    16 }
    17 
    18 int cnt[mxn];
    19 int fat[mxn];
    20 int pre[mxn];
    21 
    22 inline int find(int u)
    23 {
    24     static int stk[mxn], top;
    25     
    26     while (u != fat[u])
    27         stk[++top] = u, u = fat[u];
    28     
    29     while (top)
    30         fat[stk[top--]] = u;
    31     
    32     return u;
    33 }
    34 
    35 int opt[mxn];
    36 int num[mxn];
    37 int ans[mxn];
    38 
    39 void preDFS(int u, int f)
    40 {
    41     pre[u] = f;
    42     
    43     if (!cnt[u])
    44         fat[u] = find(f);
    45         
    46     for (int i = hd[u]; i; i = nt[i])
    47         if (to[i] != f)preDFS(to[i], u);
    48 }
    49 
    50 signed main(void)
    51 {
    52 //    freopen("tree.in", "r", stdin);
    53 //    freopen("tree.out", "w", stdout);
    54     
    55     scanf("%d%d", &n, &m);
    56     
    57     for (int i = 1, x, y; i < n; ++i)
    58         scanf("%d%d", &x, &y), add(x, y);
    59     
    60     ++cnt[1];
    61     
    62     for (int i = 1; i <= m; ++i)
    63     {
    64         static char s[5];
    65         scanf("%s%d", s, num + i);
    66         
    67         if (s[0] == 'C')
    68             opt[i] = 1, ++cnt[num[i]];
    69     }
    70     
    71     for (int i = 1; i <= n; ++i)
    72         fat[i] = i;
    73     
    74     preDFS(1, 0);
    75     
    76     for (int i = m; i >= 1; --i)
    77     {
    78         if (opt[i] == 0)
    79             ans[i] = find(num[i]);
    80         else if (--cnt[num[i]] == 0)
    81             fat[num[i]] = find(pre[num[i]]);
    82     }
    83     
    84     for (int i = 1; i <= m; ++i)
    85         if (opt[i] == 0)
    86             printf("%d
    ", ans[i]);
    87     
    88     fclose(stdin);
    89     fclose(stdout);
    90 }

    @Author: YouSiki

  • 相关阅读:
    beautifulsoup的一些使用
    requests(爬虫常用)库的使用
    find a maximum product triplet in this array
    Minimum difference between two arrays
    [LeetCode] Binary Tree Upside Down
    n 刀切多少块pizza
    Biased Random Number Generator
    linked list焦点问题,面经里很多,考虑相交不相交,有环无环 + Find Leaves of Binary Tree (Java)
    replace string use another
    Union and Intersection of two sorted list
  • 原文地址:https://www.cnblogs.com/yousiki/p/6442961.html
Copyright © 2011-2022 走看看