线段树查询
Posted minglou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树查询相关的知识,希望对你有一定的参考价值。
题目表述:
给出N个数,初始值全为0,有以下三种操作:
1.将第x个数增加y.
2.将第x个数变成y.
3.求第x个数到第y个数的和。
input:
第一行一个整数N(1<=N<=100000)N,代表数的个数。
第二行一个整数Q(1<=Q<=100000),代表询问的个数。
接下来Q行,每行第一个整数op.
如果op=1,输入x,y,表示将第x个数增加y(1<=x<=N,1<=y<=10000),
如果op=2,输入x,y,表示将第x个数变成y(1<=x<=N,1<=y<=10000),
如果op=3,输入x,y,表示求第x个数到第y个数的和(1<=x<=y<=N)。
output:
对于每次3号操作,一行输出答案。
Sample input:
3
5 1 1 1 3 1 3 1 2 4 2 1 2 3 1 2
Sample output:
1
6
1 #include<iostream> 2 using namespace std; 3 #define LT(p) (p<<1) 4 #define RT(p) (p<<1|1) 5 #define MID(l,r) ((l+r)/2) 6 const int N = 1e5+5; 7 int ans; 8 9 struct node { 10 int left,right,sum; 11 }tree[N*4]; 12 13 void pushup(int p) { 14 tree[p].sum=tree[LT(p)].sum+tree[RT(p)].sum; 15 } 16 17 void buildTree(int p,int l,int r) { 18 tree[p].left=l; 19 tree[p].right=r; 20 if(l==r) { 21 tree[p].sum=0; 22 return ; 23 } 24 buildTree(LT(p),l,MID(l,r)); 25 buildTree(RT(p),MID(l,r)+1,r); 26 pushup(p); 27 } 28 29 void update(int p,int pos,int add) { 30 if(tree[p].left==tree[p].right) { 31 tree[p].sum+=add; 32 return ; 33 } 34 else { 35 int mid=MID(tree[p].left,tree[p].right); 36 if(pos<=mid) 37 update(LT(p),pos,add); 38 else 39 update(RT(p),pos,add); 40 pushup(p); 41 } 42 43 } 44 45 void query(int p,int l,int r) { 46 if(r<tree[p].left||tree[p].right<l) { 47 return; 48 } 49 if(l<=tree[p].left&&tree[p].right<=r) { 50 ans+=tree[p].sum; 51 return ; 52 } 53 54 query(LT(p),l,r); 55 query(RT(p),l,r); 56 } 57 58 int main() { 59 int n,q; 60 cin>>n>>q; 61 buildTree(1,1,n); 62 while(q--) { 63 int a,x,y; 64 cin>>a>>x>>y; 65 if(a==1) { 66 update(1,x,y); 67 } 68 if(a==2) { 69 ans=0; 70 query(1,x,x); 71 update(1,x,y-ans); 72 } 73 if(a==3) { 74 ans=0; 75 query(1,x,y); 76 cout<<ans<<endl; 77 } 78 } 79 }
以上是关于线段树查询的主要内容,如果未能解决你的问题,请参考以下文章
AcWing 1264. 动态求连续区间和(线段树区间查询模板)