poj3321 (dfs sequence + line tree)

The meaning of the question is to give a tree, and then there are two operations. One is to ask how many apples there are in the subtree with x as the root node, and the other is to change the number of apples at a certain point.

The method is to use dfs order to transform the tree structure into linear structure, i.e. interval, and then use line segment tree to maintain. First, the in and out values of each point are required, and then the dfs order has the feature that the nodes in the subtree with X as the root node have continuous dfs order, so in[x]~out[x] corresponds to the information of this subtree. If you query, you can operate in[x]~out[x] interval.

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define ls rt<<1
#define rs (rt<<1)|1
#define fuck(x) cout<<#x<<"     "<<x<<endl;
const int maxn=1e5+10;
struct node
{
    int u,v,nxt;
}e[maxn<<1];
int head[maxn],in[maxn],out[maxn],order[maxn],sum[maxn<<2],tim;
void pushup(int rt)
{
    sum[rt]=sum[ls]+sum[rs];
}
void build(int rt,int L,int R)
{
    if(L==R)
    {
        sum[rt]=1;
        return ;
    }
    int mid=(L+R)>>1;
    build(ls,L,mid);
    build(rs,mid+1,R);
    pushup(rt);
}
void update(int rt,int L,int R,int pos)
{
    if(L==R)
    {
        if(sum[rt])
            sum[rt]=0;
        else
            sum[rt]=1;
        return ;
    }
    int mid=(L+R)>>1;
    if(pos<=mid)
        update(ls,L,mid,pos);
    else
        update(rs,mid+1,R,pos);
    pushup(rt);
}
int query(int rt,int L,int R,int l,int r)
{
    if(l<=L&&r>=R)
    {
        return sum[rt];
    }
    int mid=(L+R)>>1,ans=0;
    if(r<=mid)
        ans=query(ls,L,mid,l,r);
    else
        if(l>mid)
            ans=query(rs,mid+1,R,l,r);
        else
            ans=query(ls,L,mid,l,r)+query(rs,mid+1,R,l,r);
    return ans;
}
void dfs(int now,int fa)
{
    in[now]=++tim;
    for(int i=head[now];i!=-1;i=e[i].nxt)
    {
        if(e[i].v==fa) continue;
        dfs(e[i].v,now);
    }
    out[now]=tim;
}

int main()
{
    int n,q,cnt=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) head[i]=-1;
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        e[++cnt].u=u;
        e[cnt].v=v;
        e[cnt].nxt=head[u];
        head[u]=cnt;
        e[++cnt].u=v;
        e[cnt].v=u;
        e[cnt].nxt=head[v];
        head[v]=cnt;
    }
    dfs(1,0);
    for(int i=1;i<=n;i++) order[in[i]]=i;
    build(1,1,n);
    scanf("%d",&q);
    while(q--)
    {
        char ch;
        int k;
        scanf(" %c%d",&ch,&k);
        if(ch=='C')
            update(1,1,n,in[k]);
        else
            printf("%d\n",query(1,1,n,in[k],out[k]));
    }
    return 0;
}

 

Added by rUmX on Tue, 29 Oct 2019 22:05:14 +0200