本文共 1010 字,大约阅读时间需要 3 分钟。
建议上B站搜索线段树,播放量最多的那个视频讲的很详细。
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1000;int tr[maxn],a[maxn];//建树 void build(int i,int l,int r){ if(l == r) { tr[i] = a[l]; return; } int mid = (l+r) >> 1; build(2*i,l,mid);//左子树 build(2*i+1,mid+1,r);//右子树 tr[i] = tr[2*i] + tr[2*i+1]; //求两个子树的和 }//更新值 把id位置的值更新为val void update(int i,int l,int r,int id,int val){ if(l == r)//表示查到了id所在的节点 { a[id] = val; tr[i] = val; return ; } int mid = (l + r)>>1; //左分支 id < mid 右分支 id>mid if(id>=l && id<=mid) update(2*i,l,mid,id,val); else update(2*i+1,mid+1,r,id,val); tr[i] = tr[2*i] + tr[2*i+1];}//查询总和 ll query(int i,int l,int r,int L,int R){ if(R < l || L > r) return 0;//查询区间不在当前的访问区间内 if(L <= l && r <= R) return tr[i];//减少查询次数,查询区间包含当前访问的区间 if(l == r) return tr[i];//当前访问到一个节点直接返回值 int mid = (l+r)>>1; int suml = query(2*i,l,mid,L,R);//求左树中包含该区间的总和 int sumr = query(2*i+1,mid+1,L,R);//求右树中包含该区间的总和 return suml + sumr;//返回查询区间的总和 } int main(){ return 0;}
转载地址:http://qirq.baihongyu.com/