輝煌北大的月賽題質量真高啊,這種樹狀陣列真難想到。
樹狀陣列的基本用法是區間,單點的應用,起初這個怎麼都想不到如何套用到樹狀陣列。
轉化方法是 將樹上的節點資訊查詢,轉為深度優先中節點順序(代表結點編號)。進結點與出結點分別代表該結點管轄範圍。
題目大意級是說,給你一顆樹,最初每個節點上都有乙個蘋果,有兩種操作:修改(即修改某乙個節點,修改時這乙個節點蘋果從有到無,或從無到有)和查詢(查詢某乙個節點他的子樹上有多少個蘋果)。
由於此題資料比較大(n<=10^5),而且不是標準的二叉樹,所以這裡我們隊每乙個節點重新編號,另外為每乙個節點賦乙個左值和乙個右值,表示這個節點的管轄範圍。
也就是dfs搜尋的時候做標記的過程,這樣新的編號為1~6的節點所管轄的範圍分別就是[1,6] [2,4] [3,3] [4,4] [5,6] [6,6],其中左邊的是左值,右邊的是右值,節點1的區間是[1,6],正好這棵子樹有6個節點,其他也一樣
#include#include#include#include#include#include#includeusing namespace std;
#define n 100010
int n,m;
int lowbit(int x)
void update(int *arr,int r,int num)
int getsum(int *arr,int r)
int head[n];
int next[n];
int netb[n];
int deh1[n];
int deh2[n];
int cnt,depth;
int arr[n];
int a[n];
void init()
void add(int u,int v)
void dfs(int u)
deh2[u]=depth;//代表右
}int main()
{ int i,j,k,u,v,m;
char str[10];
while(~scanf("%d",&n))
{ init();
for(i=1;i
POJ 3321 樹狀陣列
題意 給定一棵樹,某些節點上有蘋果,多次詢問各子樹上的節點數,並且在詢問的中途隨時可能新增和刪除蘋果。分析 dfs遍歷樹的同時,對每個點標註時間,每個點有乙個開始時間和乙個結束時間,把這兩個時間當做下標,該點的蘋果個數 1或0 填入陣列的兩個對應位。子樹中結點的時間段一定是根節點時間段的子段,所以求...
poj 3321 樹狀陣列
首先對數進行dfs一下,前序優先遍歷,這樣做的目的是令節點i的子節點的編號組成的集合是一段連續的數,這樣在查詢的時候就能夠用樹狀陣列來查詢連續的區間的和 ac 如下 include include include include using namespace std const int max n...
POJ 3321 dfs 樹狀陣列
1.題目鏈結。題目大意 一棵樹上的每乙個節點在初始的時候都長了乙個蘋果,然後有這樣的兩種操作 1 q x 詢問以x為根節點的子樹上蘋果的數量 2 c x把標號為x除的狀態改變。狀態改變的意思就是原來這裡有蘋果,就變沒,原來沒有就長出來乙個,保證每個節點最多乙個蘋果。2.首先我們肯定沒有辦法離線所有的...