zoukankan      html  css  js  c++  java
  • POJ 3321 Apple Tree (树状数组)

    题意:有n个苹果被树枝连接,这是一棵树!有两种操作C ind 和 Q ind,前者是摘下ind苹果,如果没有,哪么会长出新的一个,后者是查询ind有几个子苹果。

    思路:第二道树状数组,自己想了很久不知道怎么转化,原来是利用树的性质,dfs一遍,记录每个节点的low和high值,那么他的子结点的low值和high值肯定在[low,high]之间,然后就可以通过tre[high[i]]-tre[low[i]-1]来查询当前节点的子结点个数了,汗一个,又不是自己的......

    /* Apple tree
    * 树状数组第二题,转化很经典,将树转化为数组,low[],high[]
    * 记录节点位置,树状数组求和修改O(log(n))
    */
    #include
    <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 202000;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    typedef
    struct{
    int v,next;
    }Edge;

    Edge edge[MAXN
    *20];
    int tre[MAXN],low[MAXN],net[MAXN],high[MAXN];
    int n_tre,n,cnt,index,m;
    bool visit[MAXN];

    void add_edge(const int& u,const int& v)
    {
    edge[index].v
    = v;
    edge[index].next
    = net[u];
    net[u]
    = index;
    ++index;
    edge[index].v
    = u;
    edge[index].next
    = net[v];
    net[v]
    = index;
    ++index;
    }
    int init()
    {
    cnt
    = 0;
    index
    = 0;
    CLR(tre,
    0);
    CLR(visit,
    0);
    CLR(net,
    -1);
    return 0;
    }
    int lowbit(int x)
    {
    return x&(-x);
    }
    void modify(int ind,int delta)
    {
    while( ind <= n_tre)
    {
    tre[ind]
    += delta;
    ind
    += lowbit(ind);
    }
    }
    int get_sum(int ind)
    {
    int sum = 0;
    while(ind > 0)
    {
    sum
    += tre[ind];
    ind
    -= lowbit(ind);
    }
    return sum;
    }
    int input()
    {
    int i,a,b;
    for(i = 1; i < n; ++i)
    {
    scanf(
    "%d %d",&a,&b);
    add_edge(a,b);
    }
    return 0;
    }
    void dfs(const int& u)
    {
    ++cnt;
    visit[u]
    = true;
    low[u]
    = cnt;
    for(int i = net[u]; i != -1; i = edge[i].next)
    if(!visit[edge[i].v])
    dfs(edge[i].v);
    high[u]
    = cnt;
    }
    int work()
    {
    int i,j,tmp,ind;
    int ans;
    char c[10];
    n_tre
    = n<<1;
    dfs(
    1);
    IN(m);
    CLR(visit,
    0);
    for(i = 0; i < m; ++i)
    {
    scanf(
    "%s",c);
    scanf(
    "%d",&ind);
    if(c[0] == 'Q')
    {
    ans
    =high[ind] - low[ind] + 1 +
    get_sum(high[ind])
    - get_sum(low[ind]-1);
    OUT(ans);
    }
    else
    {
    if(visit[ind])
    modify(low[ind],
    1);
    else
    modify(low[ind],
    -1);
    visit[ind]
    ^= 1;
    }
    }
    return 0;
    }
    int main()
    {
    IN(n);
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    python中type、object与class之间关系(一切皆对象)
    为什么在python中推荐使用多进程而不是多线程(转载)
    CPU密集型 VS IO密集型
    多CPU,多核,多进程,多线程
    Mac下brew安装与配置mysql
    mac安装navicat mysql破解版
    微信公众号-h5调用微信支付
    为什么js中0.1+0.2不等于0.3,怎样处理使之相等?(转载)
    gitlab安装和汉化
    PyPI使用国内源
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1718167.html
Copyright © 2011-2022 走看看