卡卡家門外有一棵蘋果樹。每年秋天,樹上都會種很多蘋果。卡卡非常喜歡蘋果,因此他一直在精心培育大蘋果樹。
問題在於,有時空叉上會長出乙個新蘋果,卡卡可能會從樹上摘下乙個蘋果作為甜點。你能幫卡卡嗎?
第一行包含乙個整數ñ(ñ ≤100,000),這是樹中的叉的數量。
接下來的n -1行分別包含兩個整數u和v,這意味著fork u和fork v通過分支連線。
下一行包含的整數中號(中號 ≤100,000)。
以下中號行,每行包含乙個訊息,該訊息或者是
「 ç x 」,這意味著蘋果上叉存在x已經變了。例如,如果叉子上有乙個蘋果,則卡卡(kaka)摘下;否則,空叉上會長出乙個新蘋果。
或「 q x 」,表示查詢叉子x上方子樹中的蘋果數量,包括叉子x上的蘋果(如果存在),
請注意,樹的開頭充滿了蘋果
對於每個查詢,每行輸出相應的答案。
312
133q 1
c 2q 1
1
2
鄰接表存邊不多說。
然後對這棵樹進行dfs遍歷,並記錄每乙個點的dfs序號(st[i]),在乙個節點的所有兒子都被遍歷過後,記錄當前en[i]為當前最大dfs序號的節點的dfs序號。
於是,我們把問題轉換為將某一點的權值改變,詢問區間[st
[x],
en[x
]][st[x],en[x]]
[st[x]
,en[
x]]的和
樹狀陣列可以輕鬆實現這些操作。
#include
#include
#include
#include
typedef
long
long ll;
using
namespace std;
ll n,m,tot,hd[
100001
],v[
100001
],c[
100001
],st[
100001
],en[
100001
],q;
struct node
a[200001];
void
add(ll x,ll y)
ll lowbit
(ll x)
void
change
(ll x,ll y)
}ll ask
(ll x)
return ans;
}void
dfs(ll k)
en[k]
=tot;
}int
main()
tot=0;
dfs(1)
;for
(int i=
1;i<=n;i++
) cin>>m;
for(ll i=
1;i<=m;i++
)else
else}}
return0;
}
這題我看了好久找不到錯關鍵是樣例還是對的,原來是陣列名打錯… POJ 3321 樹狀陣列
題意 給定一棵樹,某些節點上有蘋果,多次詢問各子樹上的節點數,並且在詢問的中途隨時可能新增和刪除蘋果。分析 dfs遍歷樹的同時,對每個點標註時間,每個點有乙個開始時間和乙個結束時間,把這兩個時間當做下標,該點的蘋果個數 1或0 填入陣列的兩個對應位。子樹中結點的時間段一定是根節點時間段的子段,所以求...
poj 3321 樹狀陣列
首先對數進行dfs一下,前序優先遍歷,這樣做的目的是令節點i的子節點的編號組成的集合是一段連續的數,這樣在查詢的時候就能夠用樹狀陣列來查詢連續的區間的和 ac 如下 include include include include using namespace std const int max n...
poj 3321 Apple Tree(樹狀陣列)
輝煌北大的月賽題質量真高啊,這種樹狀陣列真難想到。樹狀陣列的基本用法是區間,單點的應用,起初這個怎麼都想不到如何套用到樹狀陣列。轉化方法是 將樹上的節點資訊查詢,轉為深度優先中節點順序 代表結點編號 進結點與出結點分別代表該結點管轄範圍。題目大意級是說,給你一顆樹,最初每個節點上都有乙個蘋果,有兩種...