线段树
Posted lh2000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rush! ios::sync_with_stdio(false);cin.tie(0); const int inf = 0x3f3f3f3f; const long long linf = 0x3f3f3f3f3f3f3f3f; const int maxn=100005; int tree[maxn<<2]; //线段树 int lz[maxn<<2]; //懒惰数组 void pushup(int rt) { tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void pushdown(int l,int r,int rt) { if(lz[rt]) { int m=(l+r)>>1; lz[rt<<1]+=lz[rt]; lz[rt<<1|1]+=lz[rt]; tree[rt<<1]+=(m-l+1)*lz[rt]; tree[rt<<1|1]+=(r-m)*lz[rt]; lz[rt]=0; } } void build(int l,int r,int rt) { if(l==r) { cin>>tree[rt]; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } void update(int p,int add,int l,int r,int rt) //单点修改 { if(l==r) { tree[rt]+=add; return; } // pushdown(l,r,rt); //与区间修改混用时加上 int m=(l+r>>1); if(p<=m) update(p,add,lson); else update(p,add,rson); pushup(rt); } void update_range(int L,int R,int add,int l,int r,int rt) //区间修改 { if(L<=l&&R>=r) { lz[rt]+=add; tree[rt]+=(r-l+1)*add; return; } pushdown(l,r,rt); int m=(l+r)>>1; if(L<=m) update_range(L,R,add,lson); if(R>m) update_range(L,R,add,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt) //单点查询 { if(L<=l&&r<=R) { return tree[rt]; } // pushdown(l,r,rt);// 与区间修改混用时加上 int m=(l+r)>>1; int ret=0; if(L<=m) ret+=query(L,R,lson); if(R>m) ret+=query(L,R,rson); return ret; } int query_range(int L,int R,int l,int r,int rt) //区间查询 { if(L<=l&&r<=R) { return tree[rt]; } pushdown(l,r,rt); int m=(l+r)>>1; int sum=0; if(L<=m)sum+=query_range(L,R,lson); if(R>m)sum+=query_range(L,R,rson); return sum; } int main() { int t; cin>>t; while(t) { t--; int n; cin>>n; build(1,n,1); int a,b,c;cin>>a>>b>>c; update_range(a,b,c,1,n,1); cin>>a>>b; cout<<query_range(a,b,1,n,1)<<endl; } }
以上是关于线段树的主要内容,如果未能解决你的问题,请参考以下文章