洛谷 P3368 【模板】树状数组 2(线段树区间加单点查找)
題目描述
如題,已知一個(gè)數(shù)列,你需要進(jìn)行下面兩種操作:
1.將某區(qū)間每一個(gè)數(shù)數(shù)加上x
2.求出某一個(gè)數(shù)的值
輸入格式
第一行包含兩個(gè)整數(shù)N、M,分別表示該數(shù)列數(shù)字的個(gè)數(shù)和操作的總個(gè)數(shù)。
第二行包含N個(gè)用空格分隔的整數(shù),其中第i個(gè)數(shù)字表示數(shù)列第i項(xiàng)的初始值。
接下來(lái)M行每行包含2或4個(gè)整數(shù),表示一個(gè)操作,具體如下:
操作1: 格式:1 x y k 含義:將區(qū)間[x,y]內(nèi)每個(gè)數(shù)加上k
操作2: 格式:2 x 含義:輸出第x個(gè)數(shù)的值
輸出格式
輸出包含若干行整數(shù),即為所有操作2的結(jié)果。
輸入輸出樣例
輸入 #1 復(fù)制 5 5 1 5 4 2 3 1 2 4 2 2 3 1 1 5 -1 1 3 5 7 2 4 輸出 #1 復(fù)制 6 10說(shuō)明/提示
時(shí)空限制:1000ms,128M
數(shù)據(jù)規(guī)模:
對(duì)于30%的數(shù)據(jù):N<=8,M<=10
對(duì)于70%的數(shù)據(jù):N<=10000,M<=10000
對(duì)于100%的數(shù)據(jù):N<=500000,M<=500000
樣例說(shuō)明:
故輸出結(jié)果為6、10
#include <cstdio> #include <iostream> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <map> using namespace std;#define ll long long #define eps 1e-9const int inf = 0x3f3f3f3f; const int mod = 1e9+7;int n, m, ans, input[500000+8];struct node {int left, right, num; }tree[5000000+8];void build(int left, int right, int index)///建樹 {tree[index].num = 0;tree[index].left = left;tree[index].right = right;if(left == right)///如果是葉子節(jié)點(diǎn),就返回他的值return;int mid = (right+left)/2;build(left, mid, index*2);///從左邊區(qū)間開(kāi)始賦值build(mid+1, right, index*2+1);///從右邊區(qū)間開(kāi)始賦值 }void pls(int index, int l, int r, int k)///在[l, r]區(qū)間加上k值 {if(tree[index].left >= l && tree[index].right <= r)///如果這個(gè)區(qū)間在目的區(qū)間內(nèi) {tree[index].num += k;return;}if(tree[index*2].right >= l)///讓左邊的區(qū)間加kpls(index*2, l, r, k);if(tree[index*2+1].left <= r)///讓右邊的區(qū)間加kpls(index*2+1, l, r, k); }void search(int index, int dis)///尋找那個(gè)點(diǎn),并記錄他的值 {ans += tree[index].num;///記錄操作后所增加/減少的值if(tree[index].left == tree[index].right)return;if(dis <= tree[index*2].right)///如果這個(gè)數(shù)小于index這個(gè)點(diǎn)的右兒子,那就往左邊找search(index*2, dis);if(dis >= tree[index*2+1].left)///如果這個(gè)數(shù)大于index這個(gè)點(diǎn)的左兒子,那就往右邊找search(index*2+1, dis); }int main() {scanf("%d%d", &n, &m);build(1, n, 1);///初始化,給開(kāi)始的每個(gè)值賦為1for(int i = 1; i <= n; i++)scanf("%d", &input[i]);for(int i = 1; i <= m; i++){int a;scanf("%d", &a);if(a == 1){int x, y, z;scanf("%d%d%d", &x, &y, &z);pls(1, x, y, z);}else if(a == 2){ans = 0;int x;scanf("%d", &x);search(1, x);///從根節(jié)點(diǎn)開(kāi)始找x這個(gè)位置printf("%d\n", ans+input[x]);}}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/RootVount/p/11278631.html
總結(jié)
以上是生活随笔為你收集整理的洛谷 P3368 【模板】树状数组 2(线段树区间加单点查找)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: win10安装tensorflow (c
- 下一篇: git基础-打标签