線段樹之Sum
阿新 • • 發佈:2018-12-06
模板 數組 區間查詢 digi chang uil pac sample tput
題面:
給定一數列,規定有兩種操作,一是修改某個元素,二是求區間的連續和。
Input:
輸入數據第一行包含兩個正整數n,m(n<=100000,m<=500000),以下是m行,
每行有三個正整數k,a,b(k=0或1, a,b<=n).
k=0時表示將a處數字加上b,k=1時表示詢問區間[a,b]內所有數的和。
Output:
對於每個詢問輸出對應的答案。
Sample Input:
10 20
0 1 10
1 1 4
0 6 6
1 4 10
1 8 9
1 4 9
0 10 2
1 1 8
0 2 10
1 3 9
0 7 8
0 3 10
0 1 1
1 3 8
1 6 9
0 5 5
1 1 8
0 4 2
1 2 8
0 1 1
Sample Output:
10
6
0
6
16
6
24
14
50
41
Solution:
線段樹模板題,單點修改,區間詢問,tree數組維護和
Code:
#include<bits/stdc++.h> using namespace std; int n,m,a[1000001]; struct sgt{ int tree[500001]; void build(int k,int l,int r){ if(l==r){ tree[k]=a[l]; return ; } int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); tree[k]=tree[k<<1]+tree[k<<1|1]; }//建樹 void change(int x,int v,int l,int r,int k){ if(l==x&&r==x){ tree[k]+=v;return; } int mid=(l+r)>>1; if(x<=mid)change(x,v,l,mid,k<<1); else change(x,v,mid+1,r,k<<1|1); tree[k]=tree[k<<1]+tree[k<<1|1]; }//單點修改 int query(int l,int r,int L,int R,int k){ if(l>R||r<L)return 0; if(l>=L&&r<=R)return tree[k]; int re=0; int mid=(l+r)>>1; re+=query(l,mid,L,R,k<<1); re+=query(mid+1,r,L,R,k<<1|1); return re; }//區間查詢 }T;//結構體存線段樹 inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-f;ch=getchar();} while(isdigit(ch)){x=x*10+ch-48;ch=getchar();} return x*f; } int main(){ n=read();m=read(); T.build(1,1,n); for(int i=1;i<=m;i++){ int opt,l,r; opt=read();l=read();r=read(); if(opt==0)T.change(l,r,1,n,1); if(opt==1)printf("%d\n",T.query(1,n,l,r,1)); } return 0; }
線段樹之Sum