poj 3321 Apple Tree

http://poj.org/problem?id=332

本題難在轉化上面,我們可以想到用樹狀數組來做。

如右圖所示,我們要查詢2 點的時候,他的孩子爲 4  和 5 ,但是這 3 個點並不是連續的,就不能用樹狀數組來做。

所以問題的關鍵就在於,如何把一個點和它的孩子節點連續起來。

用 dfs   遞歸一個點的時候,把所有能和它相連 的點都訪問一邊,然後對應邊上序號。就和樹狀數組裏面的點對應起來。


在用vector  容器的時候,有一個地方需要注意

vector<int>v[maxn] ;   用起來會超時
typedef vector<int > INT;
vector<INT > v(maxn);  可以AC 。

#include<cstdio>
#include<vector>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 100010;
int n,cnt,s[maxn],e[maxn],c[maxn];
bool vis[maxn],apple[maxn];
//vector<int>v[maxn];
typedef vector<int > INT;
vector<INT > v(maxn);
void dfs(int cur)//遞歸調用,把能和 cur  相連的點連續起來
{
    s[cur] = ++cnt;// s  表示有 cur  開始的起點
    vis[cur] = 1;
    for(int i = 0; i< v[cur].size(); i++)
    {
        int u = v[cur][i];
        if(!vis[u]) dfs(u);
    }
    e[cur] = cnt; //  e 表示有  cur  開始的終點
    return ;
}
int lowbit(int x)
{
    return x & (-x);
}
void update(int x)
{
    int d ;
    if(apple[x])//剛開始的時候所有的點都是有蘋果的,apple  全部都是false,
    {
        apple[x] = false;
        d = -1;
    }
    else
    {
        apple[x] = true;
        d = 1;
    }
    while(x <= n)
    {
        c[x] += d;
        x += lowbit(x);
    }
}
int getsum(int x)
{
    int res = 0;
    while(x)
    {
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}
int main()
{
    char ch[2];
    while(~scanf("%d",&n))
    {
        memset(c,0,sizeof(c));
        memset(vis,0,sizeof(vis));
        int i,a,b,m;
        for(i = 1; i < n; i++)
        {
            scanf("%d%d",&a,&b);
            v[a].push_back(b);
            v[b].push_back(a);
        }
        cnt = 0;
        dfs(1);
        for(i = 1; i <= n; i++)
        {
            update(i);
            apple[i] = i;
        }
        //cout<<"****"<<endl;
        scanf("%d",&m);
        for(i = 1; i <= m; i++)
        {
            scanf("%s%d",&ch,&a);
            if(ch[0] == 'Q') printf("%d\n",getsum(e[a]) - getsum(s[a] -1));
            else
            {
                update(s[a]);
            }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章