• poj3321(dfs序+线段树)


      题意就是给一棵树,然后有2种操作,一是问以x为根节点的子树有多少苹果,二是更改某点的苹果数量。

     做法就是用dfs序把树形结构转化成线性结构也就是区间,然后用线段树维护。先要求出每个点的in和out值,然后就给每个点分配了一个新编号了,就是它的in[i],然后dfs序有个特点就是以x为根节点的子树里的节点的dfs序是连续的,所以in[x]~out[x]就对应着这颗子树的信息,查询的话对in[x]~out[x]区间操作。

    #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
    ",query(1,1,n,in[k],out[k]));
        }
        return 0;
    }
    
  • 相关阅读:
    Get IPv4 Address 2.0
    Apache Tomcat Manager 2.0
    Apache Tomcat Manager 1.0
    FTP自动登录脚本文件
    VMware Workstation 10 + CentOS-5.5-i386 + MySQL Server 5.5
    Copy Files Blurry 1.0
    Extract Chorus From Audio 1.0
    Refresh Baidu Zhidao Evaluate Num 2.0
    File Split 1.0
    其它有趣的事情分享
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754755.html
Copyright © 2020-2023  润新知