線段樹區間修改和查詢和單點查詢(線段樹模板1)

2022-06-09 04:39:12 字數 2201 閱讀 8598

如題,已知乙個數列,你需要進行下面兩種操作:

將某區間每乙個數加上 kk。

求出某區間每乙個數的和。

第一行包含兩個整數 n, mn,m,分別表示該數列數字的個數和操作的總個數。

第二行包含 nn 個用空格分隔的整數,其中第 ii 個數字表示數列第 ii 項的初始值。

接下來 mm 行每行包含 33 或 44 個整數,表示乙個操作,具體如下:

1 x y k:將區間 [x, y][x,y] 內每個數加上 kk。

2 x y:輸出區間 [x, y][x,y] 內每個數的和。

輸出包含若干行整數,即為所有操作 2 的結果。

輸入 #1複製

5 5

1 5 4 2 3

2 2 4

1 2 3 2

2 3 4

1 1 5 1

2 1 4

輸出 #1複製

11

820

對於 30\%30% 的資料:n \le 8n≤8,m \le 10m≤10。

對於 70\%70% 的資料:n \le ^3n≤103,m \le ^4m≤104。

對於 100\%100% 的資料:1 \le n, m \le ^51≤n,m≤105。

保證任意時刻數列中任意元素的和在 [-2^, 2^)[−263,263) 內。

【樣例解釋】

//四倍n

void

f(ll p,ll k)

void pushdown(ll p)

void js(ll p,ll l,ll r)

ll mid=(l+r)/2;//

中點 js(p*2

,l,mid);

js(p*2+1,mid+1

,r);

//遞迴初始化

t[p].date=t[p*2].date+t[p*2+1

].date;

//加上左右兒子節點

}void pushs(ll p,ll l,ll r,ll v)

pushdown(p);

//查詢懶標記,因為下面要遞迴

ll mid=(t[p].l+t[p].r)/2;//

取中點if(l<=mid)

if(r>mid)

t[p].date=t[p*2].date+t[p*2+1].date;//

回溯時加上左右兒子節點的值

} ll outt(ll p,ll l)

pushdown(p);

//先回覆懶標記的值再傳遞,因為下面可能遞迴(要判斷是否到了底部,就是這裡出了問題qwq)

ll mid=(t[p].l+t[p].r)/2;//

記錄中點

if(l<=mid) return outt(p*2,l);//

找左邊if(l>mid) return outt(p*2+1,l);//

找右邊

}ll check(ll p,ll l,ll r,ll x,ll y)

ll mid=(t[p].l+t[p].r)/2

; ll ans=0

; pushdown(p);

if(x<=mid)

if(mid

return

ans;

} int

main()

else

}return

0;//

華麗麗的結束,可以a掉樹狀陣列2了!!!

}

線段樹 建樹 單點修改 單點 區間查詢

線段樹 sgement tree 是一種分治思想的二叉樹結構,用於在區間上進行資訊統計。與按照二進位制位進行區間劃分的樹狀陣列相比,線段樹是一種更加通用的結構 1.線段樹的每個節點都代表乙個區間。2.線段樹具有唯一的根節點,代表的區間是整個統計範圍,如 1,n 3.線段樹的每個葉節點都代表乙個長度為...

線段樹單點修改區間查詢

這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 qq 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 input 第一行包含 2 個正整數 n,q,表示數列長度和詢...

線段樹模板(單點修改 區間查詢)

1547 例 1 區間和 時間限制 1000 ms 記憶體限制 524288 kb 提交數 2072 通過數 639 題目描述 給定一數列,規定有兩種操作,一是修改某個元素,二是求區間的連續和。輸入 輸入資料第一行包含兩個正整數n,m n 100000,m 500000 以下是m行,每行有三個正整數...