https://www.luogu.org/problemnew/show/P3374
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 #define rson (o<<1|1) 5 #define lson (o<<1) 6 const int N = 530000<<1;//zkw线段树只能查询(0,bit),所以只有bit-2个叶节点,bit-2<n要再扩大 7 int M, n, tree[N], m, q; 8 inline int read(){ 9 register int c = getchar(), x = 0, f = 1; 10 while(!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();} 11 while(isdigit(c)) x = (x<<3)+(x<<1)+(c^48), c = getchar(); 12 return x*f; 13 } 14 inline void pushup(int o){ 15 tree[o] = tree[lson] + tree[rson]; 16 } 17 inline void build(){ 18 for(M = 1; M < n; M <<= 1); 19 for(int i = 1; i <= n; ++i) tree[i+M] = read(); 20 for(int i = M-1; i; --i) pushup(i); 21 } 22 inline void update(int pos, int k){ 23 for(tree[pos+=M]+=k, pos>>=1;pos;pos>>=1) 24 pushup(pos); 25 } 26 inline int Sum(int l, int r){ 27 int ans = 0; 28 // l=l+M-1->将查询区间改为L-1,r=r+M+1->将查询区间改为R+1 29 // l^r^1 -> 相当于判断l与r是否是兄弟节点 30 for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){ 31 if (~l&1) //l%2==0 -->l左儿子 32 ans += tree[l^1]; 33 if (r&1)//r%2==1 34 ans += tree[r^1]; 35 } 36 return ans; 37 } 38 int main(void){ 39 n = read(), m = read(); 40 build(); 41 while(m--){ 42 int opt = read(), x = read(), y = read(); 43 if (opt==1) update(x,y); 44 else printf("%d\n", Sum(x,y)); 45 } 46 return 0; 47 }
ZKW线段树
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define lowbit(a) a&(-a) 5 6 const int N = 500010; 7 8 int a[N], n, m, x, y, k; 9 10 inline void update(int x, int k){ 11 while(x <= n){ 12 a[x] += k; 13 x += lowbit(x); 14 } 15 } 16 17 inline int Sum(int x){ 18 int ans = 0; 19 while(x > 0){ 20 ans += a[x]; 21 x -= lowbit(x); 22 } 23 return ans; 24 } 25 26 int main(void){ 27 scanf("%d%d", &n, &m); 28 for(int i = 1; i <= n; ++i){ 29 int tmp; scanf("%d", &tmp);update(i,tmp); 30 } 31 while(m--){ 32 int bs; 33 scanf("%d%d%d", &bs, &x, &y); 34 if (bs == 1) update(x, y); 35 else printf("%d\n", Sum(y)-Sum(x-1)); 36 } 37 38 return 0; 39 }
树状数组
原文地址:https://www.cnblogs.com/Ycrpro/p/8452478.html
时间: 2024-10-11 05:57:42