POJ 3321 Apple Tree dfs序的应用

题目链接

dfs序 说来很简单,却从来没有想到过。必须得深刻反省一下到底自己学了些啥。


题目大意是给你一棵树,动态统计某个子树的节点权值和。

同上一道题,裸算法。


利用dfs把一个树应设在一个序列上,方法是对每一次进栈出栈加一个时间戳,在这之间的点都是它的子节点。

然后就变成了动态统计区间和的问题了,

据说线段树会超。。

但是这种简单的求和问题,树状数组绝对是不二之选,用不着去折腾线段树了。


#include <cstdio>
#include <cstdlib>
#define N 210100
struct NODE {
    int v,next;
} a[N],st[N];
int h[N],t[N],P1[N],P2[N];
int tt,n,m,stn;

void dfs(int v) {
    P1[v]=++tt;
    for ( int p = a[v].next; p; p=st[p].next ) dfs(st[p].v);
    P2[v]=tt;
    return;
}

inline int l(int i) {
    return i & -i;
}

void update(int x,int k) {
    while (x<=n) {
        t[x] += k;
        x += l(x);
    }
}

int gs(int x) {
    int s =0;
    while ( x) {
        s += t[x];
        x -= l(x);
    }
    return s;
}

int main() {
    scanf("%d",&n);
    for ( int i(1); i<n; i++) {
        int a1,a2;
        scanf("%d%d",&a1,&a2);
        st[++stn].v = a2;
        st[stn].next = a[a1].next;
        a[a1].next = stn;
    }
    dfs(1);
    for ( int i(1); i<=n; i++) h[i]=1,update(P1[i],1);
    for ( scanf("%d\n",&m); m--;) {
        char ch;
        int x;
        scanf("%c%d\n",&ch,&x);
        if ( ch == 'C' ) {
            if ( h[x] ) update(P1[x],-1);
            else update(P1[x],1);
            h[x] = 1-h[x];
        } else
            printf("%d\n",gs(P2[x])-gs(P1[x]-1));
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值