樹狀陣列主要用於查詢和計算字首和,時間複雜度為o(nlogn),普通的陣列的時間複雜度o(n^2)在大資料下是不可以接受的,所以樹狀陣列是乙個非常良好的資料結構。
以上是樹狀陣列基本操作。
下面是在洛谷上做到的乙個樹狀陣列這個資料結構的應用:
題目描述
hh 有一串由各種漂亮的貝殼組成的項鍊。hh 相信不同的貝殼會帶來好運,所以每次散步完後,他都會隨意取出一段貝殼,思考它們所表達的含義。hh 不斷地收集新的貝殼,因此,他的項鍊變得越來越長。
有一天,他突然提出了乙個問題:某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答…… 因為項鍊實在是太長了。於是,他只好求助睿智的你,來解決這個問題。
輸入格式
一行乙個正整數 n,表示項鍊長度。
第二行 n 個正整數 ai,表示項鍊中第 ii 個貝殼的種類。
第三行乙個整數 m,表示 hh 詢問的個數。
接下來 m 行,每行兩個整數 l,r,表示詢問的區間。
輸出格式
輸出 m 行,每行乙個整數,依次表示詢問對應的答案。
這個題整體思路如下:
1.將每個區間按照r進行排序。
2.新增元素進樹狀陣列,當樹狀陣列序號為r時,計算tree[r]-tree[l-1]即為區間[l,r]的種類數,之後迴圈直至輸入的r完全遍歷。
**如下:
#include
#include
#define max 1000001
int tree[max]
,pre[max]
,color[max]
,n,m;
//pre儲存第i種顏色之前的位置
typedef
struct scope
scope;
intlowbit
(int n)
void
add(
int n,
int now)
//樹狀陣列核心操作×2-->更新操作
}int
sum(
int n)
return ans;
//樹狀陣列核心操作×3-->查詢操作
}void
heapsort
(scope*
,int n)
;void
heapadjust
(scope*
,int s,
int n)
;void
swap
(scope*
,int i,
int j)
;//寫的堆排對r進行排序
intmain()
scanf
("%d"
,&m)
;for
(i =
1;i <= m;i ++
)heapsort
(range,m)
;int j =1;
for(i =
1;i <= m;i ++
) answer[range[i]
.code]
=sum
(range[i]
.r)-
sum(range[i]
.l-1);
}//***這兩個迴圈就是**的主要內容***
for(i =
1;i <= m;i ++
)return0;
}void
swap
(scope *a,
int i,
int j)
void
heapsort
(scope *a,
int n)
for(i = n;i >
1;i --)}
void
heapadjust
(scope *a,
int s,
int n)
}
**主要的兩個迴圈讓我有乙個疑問點。當我把兩個迴圈的內外關係顛倒後,就是先將資料加入tree陣列,然後當序號等於r時記錄乙個answer。我想了非常久覺得這個邏輯和文中寫的迴圈的邏輯應該是乙個意思,但是全是wa,想了兩個小時了,就此作罷。 HH的項鍊 樹狀陣列
code 我洛谷部落格 點這裡某一段貝殼中,包含了多少種不同的貝殼?最開始看見這道題時,沒有思路 但再看看,可以非常明了的發現這是乙個樹狀陣列ban題 設有一長為5的項鍊 1 2 3 2 1 然後 m 3 1 52 5 1 3我的思路是這樣,由於要求的是種類數 求l 到 r 的個數 每種貝殼只能存乙...
HH的項鍊(樹狀陣列)
由於詢問的是區間中貝殼的種類數,所以問詢區間中相同種類的貝殼只有乙個會起作用 將i位置的貝殼前一次出現的位置記作pre i 種類為x的貝殼最後一次出現的位置記作f x 類似於鄰接表的nxt和had,利用pre i f x f x i來處理pre 對於每個詢問 l,r 只有pre i 也就是說所處位置...
HH的項鍊 樹狀陣列
我csdn部落格 點這裡某一段貝殼中,包含了多少種不同的貝殼?最開始看見這道題時,沒有思路 但再看看,可以非常明了的發現這是乙個樹狀陣列ban題 設有一長為5的項鍊 1 2 3 2 1 然後 m 3 1 52 5 1 3我的思路是這樣,由於要求的是種類數 求l 到 r 的個數 每種貝殼只能存乙個 不...