线段树就是一颗二叉树
不过是区间二叉树。
目前比较板子的就是,建树,区间,查最小值,增添(减少就是负向增添);
所以直接贴代码了:
希望自己可以多理解理解:
#include <bits/stdc++.h> using namespace std ; struct seg//*结构体代替左右区间和当前子节点 { int l; int r; int n; } T[150011]; void build(int l,int r,int k) //*建树 { int mid; if(l==r)//*如果只有单节点, { T[k].l=l; T[k].r=r; T[k].n=0; return ; } mid=(l+r)/2; T[k].l=l; T[k].r=r; T[k].n=0; build(l,mid,2*k);//*左树 build(mid+1,r,2*k+1);//*右树 } void insert(int n,int d,int k) //*单节点更新 。先计算节点位置再更新 { int mid; if(T[k].l==T[k].r&&T[k].l==d) { T[k].n+=n; return ; } mid=(T[k].l+T[k].r)>>1; if(d<=mid) insert(n,d,2*k); else insert(n,d,2*k+1); T[k].n=T[2*k].n+T[2*k+1].n; } int ans; void search(int l,int r,int k)//*从最高节点开始查询 { int mid; if(T[k].l==l&&T[k].r==r) { ans+=T[k].n; return ; } mid=(T[k].l+T[k].r)>>1; if(r<=mid) search(l,r,2*k); else if(l>mid) search(l,r,2*k+1); else { search(l,mid,2*k); search(mid+1,r,2*k+1); } } int main() { int Case,TT; int n; int i; int temp; char str[11]; int a,b; scanf("%d",&TT); for(Case=1; Case<=TT; Case++) { scanf("%d",&n); build(1,n,1); for(i=1; i<=n; i++) { scanf("%d",&temp); insert(temp,i,1); } printf("Case %d:\n",Case); while(scanf("%s",str),strcmp(str,"End")) { scanf("%d%d",&a,&b); if(strcmp(str,"Add")==0) insert(b,a,1); else if(strcmp(str,"Sub")==0) insert(-b,a,1); else { ans=0; search(a,b,1); printf("%d\n",ans); } } } return 0; }
多谢神牛的写法,
神牛博客地址: http://blog.csdn.net/libin56842/article/details/8530086
更新一下自己的写法,没有用结构体;
#include <bits/stdc++.h> using namespace std ; #define N 500005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int sum[N<<2]; inline void PushPlus(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int l, int r, int rt) { if(l == r) { scanf("%d", &sum[rt]); return ; } int m = ( l + r )>>1; build(lson); build(rson); PushPlus(rt); } void updata(int p, int add, int l, int r, int rt) { if( l == r ) { sum[rt] += add; return ; } int m = ( l + r ) >> 1; if(p <= m) updata(p, add, lson); else updata(p, add, rson); PushPlus(rt); } int search(int L ,int R ,int l , int r , int rt) { int ans = 0 ; if(L<=l&&R>=r) { return sum[rt]; } int m = (l+r)>>1; if(L<=m) ans += search(L,R,lson); if(R>m) ans += search(L,R,rson); return ans ; } int main() { int t ; cin>>t; char str[5000]; for(int i=1;i<=t;i++) { int n ; int a , b ; cin>>n; build(1,n,1); printf("Case %d:\n",i); while(scanf("%s",str)&&str[0]!='E') { cin>>a>>b; int m; if(str[0]=='Q') { m=search(a,b,1,n,1); cout<<m<<endl; } else if(str[0]=='A') { updata(a,b,1,n,1); } else { updata(a,-b,1,n,1); } } } return 0 ; }