首页 > 代码库 > POJ 3321 Apple Tree (dfs+线段树)

POJ 3321 Apple Tree (dfs+线段树)

题目大意:

修改树上的节点,然后求子树的和。


思路分析:

dfs 重新编号,烂大街了。。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 100005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
using namespace std;

int num[maxn];
int ed[maxn];
int tot[maxn<<2];

void pushup(int num)
{
    tot[num]=tot[num<<1]+tot[num<<1|1];
}
void build(int num,int s,int e)
{
    if(s==e)
    {
        tot[num]=1;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
    pushup(num);
}
void update(int num,int s,int e,int pos)
{
    if(s==e)
    {
        tot[num]^=1;
        return;
    }
    int mid=(s+e)>>1;
    if(pos<=mid)update(lson,pos);
    else update(rson,pos);
    pushup(num);
}
int query(int num,int s,int e,int l,int r)
{
    if(l<=s && r>=e){
        return tot[num];
    }
    int mid=(s+e)>>1;
    if(r<=mid)return query(lson,l,r);
    else if(l>mid)return query(rson,l,r);
    else return query(lson,l,mid)+query(rson,mid+1,r);
}

int id;
int next[maxn<<1];
int head[maxn];
int to[maxn<<1];
void addedge(int u,int v)
{
    id++;
    next[id]=head[u];
    to[id]=v;
    head[u]=id;
}

int cnt=1;
bool vis[maxn];

int dfs(int cur)
{
    num[cur]=cnt++;
    ed[num[cur]]=num[cur];
    for(int p=head[cur]; p ;p=next[p])
    {
        if(vis[to[p]])continue;
        vis[to[p]]=true;
        ed[num[cur]] = max(ed[num[cur]],dfs(to[p]));
    }
    return ed[num[cur]];
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(vis,false,sizeof vis);
        memset(head,0,sizeof head);
        memset(ed,0,sizeof ed);
        id=0,cnt=1;

        for(int i=1;i<=n-1;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }

        vis[1]=true;
        dfs(1);

        int m;
        scanf("%d",&m);
        char str[2];
        build(1,1,cnt-1);
        while(m--)
        {
            int op;
            scanf("%s%d",str,&op);
            if(str[0]=='Q')
            {
                printf("%d\n",query(1,1,cnt-1,num[op],ed[num[op]]));
            }
            else update(1,1,cnt-1,num[op]);
        }
    }
    return 0;
}
/*
4
1 2
1 3
2 4
2 5

*/