1. 程式人生 > >nefu 1330 樹上計算 (dfs序+樹狀陣列)

nefu 1330 樹上計算 (dfs序+樹狀陣列)

樹上計算

Problem:1330

Time Limit:1000ms

Memory Limit:65535K

Description


給出一棵以 1 為根的樹,初始每個頂點的權值為 0 。
現有兩種操作: 1 x 代表將頂點 x 的權值加一 
             2 x 詢問頂點 x 的子樹(包含x本身)的權值和是多少

Input


第一行樣例個數 T (T<=10)
對於每組樣例
第一行是一個數 N 代表頂點的個數(1 <= N <= 4e4)
隨後 N - 1 行每行有兩個數 x y 代表頂點 x y 由一條邊相連·
接下來一行是一個數 M 代表操作的次數(1<= M <=4e4)
最後 M 行,每行兩個數 1 x 或 2 x 代表操作(1 <= x <= N)

Output


每次詢問輸出答案,每個答案佔一行。

Sample Input


10
9
1 2
1 3
2 4
2 5
3 6
6 8
6 7
8 9
9
2 1
1 3
2 6
1 6
1 3
2 1
2 8
1 2
2 1
9
1 2
1 3
2 4
2 5
3 6
3 7
6 8
6 9
5
1 6
2 8
1 3
1 4
2 1

Sample Output


0
0
3
0
4
0
3

Hint

Source


DT2131
題意:

中文題。

思路:

先用dfs求出他們的dfs序,ls到rs是他們的子樹包括他們自己本身。這樣我們就掌握了每個節點他們的子樹是什麼了。我們只需要一個能單點更新和區間查詢的資料結構就行了。樹狀陣列比較好寫,我們就用樹狀陣列來完成這件事。

程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=4e4+500;
int ls[maxn],rs[maxn];
vector<int> v[maxn];
int cnt;
int tr[maxn];
int lowbit(int i)
{
    return i&(-i);
}
void update(int i,int n,int c)
{
    while(i<=n)
    {
        tr[i]+=c;
        i+=lowbit(i);
    }
}
int query(int n)
{
    int sum=0;
    while(n>0)
    {
        sum+=tr[n];
        n-=lowbit(n);
    }
    return sum;
}
void dfs(int now,int fa)
{
    ls[now]=++cnt;
    for(int i=0;i<v[now].size();i++)
    {
        if(v[now][i]==fa)
            continue;
        dfs(v[now][i],now);
    }
    rs[now]=cnt;
}
int main()
{
    int t,n,x,y,m,o;
    scanf("%d",&t);
    while(t--)
    {
        memset(tr,0,sizeof(tr));
        scanf("%d",&n);
        cnt=0;
        for(int i=1;i<=n;i++)
            v[i].clear();
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        dfs(1,0);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&o,&x);
            if(o==1)
            {
                update(ls[x],n,1);
            }
            else
            {
                printf("%d\n",query(rs[x])-query(ls[x]-1));
            }
        }
    }
    return 0;
}