• POJ


    题目链接:http://poj.org/problem?id=3321

    题目大意:给定一棵树,某些节点上有苹果,多次询问各子树上的节点数,并且在询问的中途随时可能新增和删除苹果。

    Sample Input

    3
    1 2
    1 3
    3
    Q 1
    C 2
    Q 1
    

    Sample Output

    3
    2

    emmm,刚开始的时候还以为是个树剖呢,板子都打好了。。。它要的是整个子树,所以我们利用dfs序将整个树化为一个序列,然后跑线段树就行了,跑dfs的时候记录一下进入时间戳和出去的时间戳。

    以下是AC代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define lc rt<<1
    #define rc rt<<1|1
    const int mac=1e5+10;
    
    struct Edge
    {
        int to,next;
    }eg[mac<<1];
    int num=0,head[mac],in[mac],out[mac],id;
    int tree[mac<<2];
    
    void add(int u,int v)
    {
        eg[num].to=v;eg[num].next=head[u];
        head[u]=num++;
    }
    
    void dfs(int x,int fa)
    {
        in[x]=++id;
        for (int i=head[x]; i!=-1; i=eg[i].next){
            int v=eg[i].to;
            if (v==fa) continue;
            dfs(v,x);
        }
        out[x]=id;
    }
    
    void build(int l,int r,int rt)
    {
        if (l==r) {tree[rt]=1; return;}
        int mid=(l+r)>>1;
        build(lson);build(rson);
        tree[rt]=tree[lc]+tree[rc];
    }
    
    void update(int l,int r,int rt,int pos)
    {
        if (l==r) {tree[rt]^=1; return;}
        int mid=(l+r)>>1;
        if (mid>=pos) update(lson,pos);
        else {update(rson,pos);}
        tree[rt]=tree[lc]+tree[rc];
    }
    
    int query(int l,int r,int rt,int L,int R)
    {
        int ans=0;
        if (l>=L && r<=R) return tree[rt];
        int mid=(l+r)>>1;
        if (mid>=L) ans+=query(lson,L,R);
        if (mid<R) ans+=query(rson,L,R);
        return ans;
    }
    
    int main(int argc, char const *argv[])
    {
        int n,q;
        scanf ("%d",&n);
        memset(head,-1,sizeof head);
        for (int i=1; i<=n-1; i++){
            int u,v;
            scanf ("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        scanf ("%d",&q);
        dfs(1,0);
        build(1,n,1);
        for (int i=1; i<=q; i++){
            char s[5];
            int x;
            scanf ("%s%d",s,&x);
            if (s[0]=='Q') printf("%d
    ",query(1,n,1,in[x],out[x]));
            else update(1,n,1,in[x]);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    动手动脑篇之类与对象
    团队精神
    在快乐中学习
    实习报告
    大道至简读后感(二)
    大道至简读后感
    读《大道至简》第一章有感
    指令随笔之:tail、cat、scp、&、&&、;、|、>、>>
    NFS安装过程
    CentOS7编译安装Nginx-1.8.1和编译参数
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13275288.html
Copyright © 2020-2023  润新知