題意: 輸入n個數字,查詢區間[l,r]中有多少個不同的數字
(第i個數字為a[i])
思路:要維護的是不同的數字的數量,所以每個數隻記最後出現的那一次。對n個位置每個位置建一棵線段樹,線段樹維護的是插入
a[i]後樹上各區間數字的數量。如果a[i]這個數字在前面被插入過,就在新建的樹中把 包含a[i]的上乙個位置的 所有區間 的
值-1,然後再照常插入a[i],因此要用乙個陣列記錄a[i]上次插入時的位置。查詢時只要查r對應的版本的線段樹就行了。
#include
using namespace std;
const
int maxn =
30010
;int t[maxn*30]
,tot,rts[maxn]
,lson[maxn*30]
,rson[maxn*30]
;void
add(
int pos,
int val,
int l,
int r,
int&rt,
int lst)
intquery
(int l,
int r,
int l,
int r,
int rt)
int n,a[maxn]
,x,y,q,past[
1000005];
intmain()
else
add(i,1,
1,n,rts[i]
,rts[i-1]
);past[a[i]
]= i;
}scanf
("%d"
,&q)
;while
(q--
)return0;
}
SPOJ 3267 DQUERY(離線 樹狀陣列)
傳送門 話說這好像hh的項鍊啊 然後就說一說上次看到的一位大佬很厲害的辦法吧 對於所有 r 相等的詢問,需要統計有多少個不同的數,那麼對於同乙個數字,我們只需要關心它最右邊的那乙個 比如 1,2,3,4,1,2 對於所有 r 5 的詢問,我們不用去管第乙個 1 因為它一定可以被第五個 1 代替 同理...
可持久化線段樹總結(可持久化線段樹,線段樹)
最近正在學習一種資料結構 可持久化線段樹。看了網上的許多部落格,弄了幾道模板題,思路有點亂了,所以還是來總結整理下吧。你需要維護這樣的乙個長度為 n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一...
可持久化線段樹
可持久化線段樹,意思是可以查詢歷史記錄的線段樹。又叫主席樹。我們可以通過記錄不同的根節點,並在每乙個更新到的節點處新建必要的節點。詢問不同版本的主席樹,只需要進入不同的根節點即可。例題 給定n,m,輸入n個數組成的數列,有m個詢問,每次詢問l,r這個區間中,第k小的數的值。分析 這個題可以巧妙運用主...