• poj 3321


    题目链接

    题意:一开始1-n都有苹果,Q查询以x为根下存在多少。

    树状数组+DFS+队列转换

    这题纠结了2天,一开始一点思路都没有,看大神都是吧树状数组转换成队列来做

    看了好久都不知道怎么转换的,

    解决方法:用两个队列,一个是以记录(s,u),s为起点,一个记录s,为终点

    用DFS查找一棵分支,记录访问次序,这样就可以转换成树状数组了

    #include <cstdio> //参照大神的代码
    #include <cstring>
    using namespace std;
    #define N 500000
    int tree[N],b[N],e[N],head[N];  //b记录DFS访问的次序,e表示当前节点DFS的最后一个节点标号
    bool h[N],v[N]; //v[i]表示是否被访问过
    int num;
    struct node
    {
        int x,next;
    }a[N];
    inline int lowbit(int x) {return x&-x;}
    void update(int x,int t)
    {
        int n;
        if(h[t]) {h[t]=false;n=-1;} //false 表示没有
        else {h[t]=true;n=1;}
        while(x<=num)
        {
            tree[x]+=n;
            x+=lowbit(x);
        }
    }
    int getsum(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }
    void dfs(int x)
    {
        v[x]=true;
        b[x]=++num;
        for(int i=head[x];i!=-1;i=a[i].next)
        {
            if(!v[a[i].x])
                dfs(a[i].x);
        }
        e[x]=num;
      //printf("%d  %d %d
    ",x,num,b[x]);
    }
    int main()
    {
        int n,i,j;
        while(scanf("%d",&n)!=EOF)
        {
            int m=0;
            memset(tree,0,sizeof(tree));
            memset(head,-1,sizeof(head));
            for(i=1;i<n;i++)
            {
                int s,u;
                scanf("%d%d",&s,&u);
                m++;
                a[m].x=u;a[m].next=head[s];head[s]=m;
                m++;
                a[m].x=s;a[m].next=head[u];head[u]=m;
            }
            memset(v,false,sizeof(v));
            memset(b,0,sizeof(b));
            memset(e,0,sizeof(e));
            num=0;
            dfs(1);
            for(i=1;i<=n;i++)
            {
                update(b[i],i);
                h[i]=true;
            }
            char str[10];
            int t,mm;
            scanf("%d",&mm);
            for(i=1;i<=mm;i++)
            {
                scanf("%s%d",str,&t);
                if(str[0]=='C')
                update(b[t],t);
                else
                printf("%d
    ",getsum(e[t])-getsum(b[t]-1));
            }
        }
        return 0;
    }
    


     

  • 相关阅读:
    Ajax调用 打不开新窗口
    杂记3
    todo WebClient学习
    Repeater 嵌套
    动态生成数个gridview Button得到隐藏ID列的值
    SQL 查询间隔时间大于60s的所有数据
    Apache DbUtils
    一步步学Mybatis-告别繁琐的配置之Mybatis配置文件生成工具 (7)
    一步步学Mybatis-怎么样实现动态SQL查询(6)
    一步步学Mybatis-实现简单的分页效果逻辑 (5)
  • 原文地址:https://www.cnblogs.com/james1207/p/3281255.html
Copyright © 2020-2023  润新知