zoukankan      html  css  js  c++  java
  • POJ 3321 Apple Tree

    题目链接:【http://poj.org/problem?id=3321】

    题意:给你一棵树,有两种操作,第一种是对某个节点进行修改(该节点如果有苹果,就拿掉,如果没有苹果就放上去一个),第二种操作是询问以节点x为根的子树上有多少苹果。

    题解:对一棵树进行DFS,对每一个节点重新编号,并记录下某个节点出的时候当前结点的最大值,也就是说记录了每个节点的编号和这个节点为根所表示的最大区间。这样就可以对利用单点修改区间求和进行求解。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 1e6 + 15;
    int N, M;
    struct Edge
    {
        int to, next;
        Edge (int to = 0, int next = 0): to(to), next(next) {}
    } E[maxn];
    int head[maxn], tot;
    void initEdge()
    {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void addEdge(int u, int v)
    {
        E[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    int L[maxn], R[maxn], dfs_clock;
    void DFS(int u, int fa)
    {
        L[u] = ++dfs_clock;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].to;
            if(v == fa) continue;
            DFS(v, u);
        }
        R[u] = dfs_clock;
    }
    int sum[maxn], vis[maxn];
    int low_bit(int x)
    {
        return x & (-x);
    }
    void add_Sum(int p, int val)
    {
        while(p <= N)
        {
            sum[p] += val;
            p += low_bit(p);
        }
    }
    int get_Sum(int p)
    {
        int ret = 0;
        while(p)
        {
            ret += sum[p];
            p -= low_bit(p);
        }
        return ret;
    }
    int main ()
    {
        initEdge();
        scanf("%d", &N);
        for(int i = 1; i <= N - 1; i++)
        {
            int u, v;
            scanf("%d %d", &u, &v);
            addEdge(u, v);
            addEdge(v, u);
        }
        DFS(1, 0);
        for(int i = 1; i <= N; i++)
        {
            add_Sum(i, 1);
            vis[i] = 1;
        }
        scanf("%d", &M);
        for(int i = 1; i <= M; i++)
        {
            char s[5];
            int  p;
            scanf("%s %d", s + 1, &p);
            if(s[1] == 'C')
            {
                if(vis[L[p]])
                    add_Sum(L[p], -1);
                else
                    add_Sum(L[p], 1);
                vis[L[p]] ^= 1;
            }
            else if(s[1] == 'Q')
            {
                int t1 = get_Sum(R[p]);
                int t2 = get_Sum(L[p] - 1);
                printf("%d
    ", t1 - t2);
            }
        }
        return 0;
    }
  • 相关阅读:
    linux每日命令(29): chown命令
    linux每日命令(28): charp命令
    linux每日命令(27): chmod命令
    linux每日命令(26):Linux文件属性详解
    linux每日命令(25): linux文件类型与扩展名
    linux每日命令(24): linux目录结构
    linux每日命令(23): find命令之xargs
    linux每日命令(22): find命令参数详解
    2017年12月31日
    Python使用otp实现二步验证
  • 原文地址:https://www.cnblogs.com/pealicx/p/7297649.html
Copyright © 2011-2022 走看看