poj 3321(dfs序&&树状数组)

第一次知道dfs序这个东西,可以维护树上的任意一个节点,以这个节点为根的子树上的所有节点的标号。是连续的一段区间。

一棵子树的所有节点在dfs序里是连续一段,主要就是利用这个性质来解题

然后就是树状数组维护区间内苹果的数量

另外这个题很卡时间,我用了输入输出挂才过

#include<cstdio>
#include<vector>
using namespace std;
const int maxn = 100000+10;
vector<int>G[maxn];
int l[maxn],r[maxn];
int tree[maxn];
char op[5];
int x,key,n;
inline int in()
{
    char ch;
    int a = 0;
    while((ch = getchar()) == ' ' || ch == '\n');
    a += ch - '0';
    while((ch = getchar()) != ' ' && ch != '\n')
    {
        a *= 10;
        a += ch - '0';
    }
    return a;
}
void dfs(int u)
{
    l[u] = key;
    int len = G[u].size();
    for(int i=0;i<len;i++)
    {
        int v = G[u][i];
        key++;
        dfs(v);
    }
    r[u] = key;
}
inline int lowbit(int i){return i&(-i);}
inline void add(int i,int x)
{
    while(i<=n)
    {
        tree[i] += x;
        i += lowbit(i);
    }
}
inline int getsum(int i)
{
    int sum = 0;
    while(i)
    {
        sum += tree[i];
        i -= lowbit(i);
    }
    return sum;
}
int q[maxn];
inline void Out(int a)
{   //  输出外挂
    if (a < 0)
    {
        putchar('-');
        a = -a;
    }
    if (a >= 10)
    {
       Out(a / 10);
    }
    putchar(a % 10 + '0');
}
int main()
{
    int u,v;
    n = in();
    for(int i=1;i<n;i++)
    {
        u = in(); v = in();
        G[u].push_back(v);
    }
    key = 1;
    dfs(1);
    for(int i=1;i<=n;i++) q[i] = 1,add(i,1);
    int m;
    scanf("%d",&m);
    while(m--)
    {
        scanf("%s%d",op,&x);
        if(op[0]=='Q')
        {
            Out(getsum(r[x])-getsum(l[x]-1)); puts("");
        }
        else
        {
            if(q[x]==1) add(l[x],-1),q[x]=0;
            else add(l[x],1),q[x] = 1;
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值