zoukankan      html  css  js  c++  java
  • POJ3321Apple Tree Dfs序 树状数组

    出自——博客园-zhouzhendong

    ~去博客园看该题解~

    题目

    POJ3321 Apple Tree

     

    题意概括

    有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作:

      1.改变其中一个结点的权值(0变1,1变0)

      2.询问子树X的节点权值和。

     

    输入描述

    一组数据。

    先是一个数n,表示有n个节点。

    接下去n-1行,每行表示一条边。

    然后一个数m,表示有m个操作。

    然后m行,每行一个字母一个数x,如果字母是Q,则是询问;否则是修改。

     

    输出描述

    每一个询问一行,表示答案。

     

    题解

     

    直接把题目变成dfs序上单点修改和区间sum询问的问题。

    单点修改,不用线段树,树状数组就可以了。

    如果你非要用线段树我也不拦你……

     

    代码

     

    #pragma comment(linker,"/STACK:1024000000,1024000000") 
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=100000+5,M=N*2;
    struct Edge{
        int cnt,y[M],nxt[M],fst[N];
        void set(){
            cnt=0;
            memset(fst,0,sizeof fst);
        }
        void add(int a,int b){
            y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
        }
    }e;
    int n,m;
    int in[N],out[N],time;
    int tree[N],v[N];//树状数组 
    int lowbit(int x){
        return x&-x;
    }
    void dfs(int prev,int rt){
        in[rt]=++time;
        for (int i=e.fst[rt];i;i=e.nxt[i])
            if (e.y[i]!=prev)
                dfs(rt,e.y[i]);
        out[rt]=time;
    }
    void update(int x,int d){
        for (;x<=n;x+=lowbit(x))
            tree[x]+=d;
    }
    int sum(int x){
        int ans=0;
        for (;x>0;x-=lowbit(x))
            ans+=tree[x];
        return ans;
    }
    int query(int L,int R){
        return sum(R)-sum(L-1);
    }
    int main(){
        e.set();
        scanf("%d",&n);
        for (int i=1,a,b;i<n;i++){
            scanf("%d%d",&a,&b);
            e.add(a,b);
            e.add(b,a);
        }
        time=0;
        dfs(0,1);
        for (int i=1;i<=n;i++)
            tree[i]=lowbit(i),v[i]=1;
        scanf("%d",&m);
        for (int i=1,x;i<=m;i++){
            char ch[2];
            scanf("%s%d",ch,&x);
            if (ch[0]=='Q')
                printf("%d
    ",query(in[x],out[x]));
            else
                update(in[x],1-v[x]*2),v[x]^=1;
        }
        return 0;
    }
  • 相关阅读:
    【转】运行维护管理制度
    系统负载超预警 问题定位
    19-多进程学习
    3-Pandas层次化索引&拼接
    2-Anaconda简介&Numpy基础
    1-IPython&jupyter notebook
    18-进程&协程
    17-多线程
    16-网络通信
    15-正则表达式
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/POJ3321.html
Copyright © 2011-2022 走看看