zoukankan      html  css  js  c++  java
  • 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;
    }
    


     

  • 相关阅读:
    CentOS Grub、BASH 故障、解决方法
    Fail2ban 阻止暴力破解
    Extundelete 数据恢复
    HTTP 状态信息
    LNMP 参数调优 ( 无注释 )
    Mysql 性能优化 ( my.cnf )
    MantisBT 缺陷管理系统
    Zabbix Agent 源码编译安装
    Zabbix 监控 Mysql 状态
    Zabbix 监控 Nginx 状态
  • 原文地址:https://www.cnblogs.com/james1207/p/3281255.html
Copyright © 2011-2022 走看看