題目描述 description 一行n個方格,開始每個格仔裡都有乙個整數。現在動態地提出一些問題和修改:提問的形式是求某乙個特定的子區間[a,b]中所有元素的和;修改的規則是指定某乙個格仔x,加上或者減去乙個特定的值a。現在要求你能對每個提問作出正確的回答。1≤n<100000,,提問和修改的總數m<10000條。
輸入描述 input description 輸入檔案第一行為乙個整數n,接下來是n行n個整數,表示格仔中原來的整數。接下乙個正整數m,再接下來有m行,表示m個詢問,第乙個整數表示詢問代號,詢問代號1表示增加,後面的兩個數x和a表示給位置x上的數值增加a,詢問代號2表示區間求和,後面兩個整數表示a和b,表示要求[a,b]之間的區間和。
輸出描述 output description 共m行,每個整數
樣例輸入 sample input 6
4 5
6 2 1 3
41 3 5
2 1 4
1 1 9
2 2 6
樣例輸出 sample output 22
22資料範圍及提示 data size & hint 1≤n<100000, m<10000 。
[cpp]view plain
copy
print?
# include
# define n 500000
// 利用二叉樹的父子節點關係來儲存,因此必須保證陣列開的足夠大
struct
node;
node st[n];
inta[n];
void
build(
intv,
intl,
intr)
intmid = (l+r)/2;
// 不是葉子,往下擴充套件
build(2*v,l,mid);
build(2*v+1,mid+1,r);
st[v].v=st[v*2].v+st[v*2+1].v; // 擴充套件出孩子後才能計算value域
} void
insert(
intv,
intw,
intp)
if(st[v].l==st[v].r)
return
;
// 找到終點,跳出
intmid = (st[v].l+st[v].r)/2;
if(w<=mid) else
} intgetsum(
intv,
intl,
intr)
intmid = (st[v].l+st[v].r)/2;
if(r<=mid) else
if(l>mid) else
} intmain(
void
) build(1,1,n);
intm,t,a,b;
for(scanf(
"%d"
,&m);m;m--)else
} return
0;
}
線段樹入門
線段樹 interval tree 是把區間逐次二分得到的一樹狀結構,它反映了包括歸併排序在內的很多分治演算法的問題求解方式。上圖是一棵典型的線段樹,它對區間 1,10 進行分割,直到單個點。這棵樹的特點 是 1.每一層都是區間 a,b 的乙個劃分,記 l b a 2.一共有log2l層 3.給定乙...
線段樹入門
學習下 線段樹的入門級 總結 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹,最後的子節點數目為...
線段樹 入門
首先線段樹形象來說就是將陣列看成乙個線段,然後不斷的進行分割,儲存在樹中的不同節點上,有點類似於b 樹的定義吧 觀察上圖,首先將整個陣列的某種資訊 最大值或者最小值等 儲存在根節點,對應 1,8 然後對 1,8 線段進行平分,得到 1,4 和 5,8 兩個線段,掛在樹的第二層。這樣節點2儲存了陣列中...