zoukankan      html  css  js  c++  java
  • poj 3321 dfs序 树状数组 前向星

    题意概括

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

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

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

    参考博客 http://www.cnblogs.com/zhouzhendong/p/7265431.html

    思路 :dfs序  +树状数组

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

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

    用vector存图超时。。改用的前向星

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    const int N = 1E5+3;
    const int M = 2E5+3;
    #define pb push_back
    int n;
    int in[N],out[N];
    int time;
    int vis[N];
    int tree[N],a[N];
    struct edge{
        int cnt,y[M],nxt[M],head[N];
        void clc(){
            cnt =0 ;
            memset(head,0,sizeof(head));
        }
        void add(int a,int b){
            y[++cnt]=b;
            nxt[cnt]=head[a];head[a]=cnt;
        }
    }E;
    
    
    void dfs(int t){
        in[t]=++time;
        vis[t]=1;
        for(int i =E.head[t];i;i=E.nxt[i]){
            if(vis[E.y[i]])continue;
            vis[E.y[i]]=1;
            dfs(E.y[i]);
        }
        out[t]=time;
    }
    int lowbit(int x){
        return x&-x;
    }
    int sum(int x){
        int ans=0;
        for(;x>0;x-= x&-x){
            ans+=tree[x];
        }
        return ans;
    }
    void update(int x,int val){
        for(;x<=n;x+= x&-x)
            tree[x]+=val;
    }
    
    
    int main(){
    
        int u,v;
        char s[22];int x;
        while(cin>>n){
    
            time=0;
            memset(vis,0,sizeof(vis));
            E.clc();
            for(int i=1;i<n;++i){
                scanf("%d %d",&u,&v);
                E.add(u,v);
            }
            for(int i=1;i<=n;++i)a[i]=1,tree[i]=lowbit(i);
    
            dfs(1);
    
            int q;
            cin>> q;
            while(q--){
                scanf("%s %d",s,&x);
                if(s[0]=='Q'){
                    printf("%d
    ",sum(out[x])-sum(in[x]-1) );
                }
                else if(s[0]=='C'){
                    update(in[x] ,1-a[x]*2),a[x]=a[x]^1;
                }
            }
        }
        return 0;
    }

     

  • 相关阅读:
    同一部电脑配两个git账号
    在span中,让里面的span垂直居中用这个
    三张图搞懂JavaScript的原型对象与原型链
    vue2.0 生命周期
    js中__proto__和prototype的区别和关系?
    【转】css 包含块
    【转】BFC(block formating context)块级格式化上下文
    javascript中函数的5个高级技巧
    toString() 和 valueOf()
    桌面图标列表排列小工具
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/9827196.html
Copyright © 2011-2022 走看看