如題,已知乙個數列,你需要進行下面兩種操作:
將某區間每乙個數加上 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複製1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
11對於 30\%30% 的資料:n \le 8n≤8,m \le 10m≤10。820
對於 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行,每行有三個正整數...