POJ 3321 Apple Tree(dfs序+树状数组)

题目链接
题意:就是给你一个树,每次动态修改一个节点的值,然后问你某一颗子树的节点值的和。
做法:很明显每次修改然后dfs一次是会超时的,所以先跑一遍dfs,给树映射到区间,然后树状数组求和,dfs序,就是每次记录访问到这个节点的时间戳以及访问其儿子节点结束后返回该点的结束时间戳,那么他的儿子节点就是在这2个时间戳之间了,就把树转换为区间了,剩下的就好办了。vector会TLE,所以使用结构存储边。



//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define LL long long
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn=100005;
const  LL inf=1LL<<32;
double pi=acos(-1.0);
#define gcd __gcd
#define LCM(a,b) (a)*(b)/gcd(a,b)
#define X first
#define Y second
#define pb push_back
#define lowbit(s) (s&(-s))

int cnt,tot;
struct Edge{
    int to,next;
}edge[maxn];
int head[maxn];
void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int st[maxn],en[maxn];
void dfs(int u){
    st[u]=++cnt;
    for(int i=head[u];~i;i=edge[i].next)dfs(edge[i].to);
    en[u]=cnt;
}
int c[maxn];
void update(int x,int val){
    for(int i=x;i<maxn;i+=lowbit(i)){
        c[i]+=val;
    }
}
int sum(int x){
    int ret=0;
    for(int i=x;i;i-=lowbit(i))ret+=c[i];
    return ret;
}
int h[maxn];
int main(){
    cl(head,-1);
    int n;scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        addedge(x,y);
    }
    dfs(1);int q;
    for(int i=1;i<=n;i++){
        update(st[i],1);h[i]=1;
    }
    char op[3];
    scanf("%d",&q);
    while(q--){
        int num;
        scanf("%s%d",op,&num);
        if(op[0]=='Q'){
            printf("%d\n",sum(en[num])-sum(st[num]-1));
        }
        else {
            if(h[num]){
                update(st[num],-1);
            }
            else {
                update(st[num],1);
            }
            h[num]=!h[num];
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值