线段树专题
Posted h404nofound
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树专题相关的知识,希望对你有一定的参考价值。
先存个ABC板子题orz
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define fi first 4 #define se second 5 #define tl rt<<1 6 #define tr rt<<1|1 7 #define pi acos(-1.0) 8 #define mp make_pair 9 #define pb push_back 10 #define ls rt<<1,l,mid 11 #define rs rt<<1|1,mid+1,r 12 #define pll pair<LL, LL> 13 #define pii pair<int, int> 14 #define mem(a, b) memset(a, b, sizeof(a)) 15 #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 16 17 typedef long long ll; 18 const int N = 2e5+5; 19 20 int a[N]; 21 struct node{ 22 int l,r,sum; 23 }b[N]; 24 void Build(int rt,int l,int r){//构造 25 b[rt].l = l,b[rt].r = r; 26 if(l==r){ 27 b[rt].sum = a[l];return ; 28 } 29 int mid = (l+r)>>1; 30 Build(ls);Build(rs); 31 b[rt].sum = b[tl].sum + b[tr].sum; 32 } 33 void AS(int rt,int tot,int cnt){//单点修改 34 if(b[rt].l==b[rt].r){ 35 b[rt].sum += tot;return ; 36 } 37 b[rt].sum += tot; 38 if(cnt<=b[tl].r)AS(tl,tot,cnt); 39 else AS(tr,tot,cnt); 40 } 41 int query(int rt,int l,int r){//区间询问 42 if(b[rt].l==l&&b[rt].r==r)return b[rt].sum; 43 int mid = (b[rt].l+b[rt].r)>>1; 44 if(r<=mid)return query(tl,l,r); 45 else if(l>mid)return query(tr,l,r); 46 else return query(ls)+query(rs); 47 } 48 int main(){ 49 int t,n,num,j, k = 0; 50 string ed = "End",que = "Query",ad = "Add",sb = "Sub",s; 51 fio 52 cin>>t; 53 while(t--){ 54 cin>>n; 55 for(int i = 1;i <= n;++i)cin>>a[i]; 56 cout<<"Case "<<++k<<":"<<endl; 57 Build(1,1,n); 58 while(1){ 59 cin>>s; 60 if(s==ed)break; 61 cin>>j>>num; 62 if(s==que)cout<<query(1,j,num)<<endl; 63 if(s==ad)AS(1,num,j); 64 if(s==sb)AS(1,-num,j); 65 } 66 } 67 return 0; 68 }
1 struct node{ 2 int l,r,maxx; 3 }b[4*N]; 4 void Build(int rt,int l,int r){//构造区间最大值 5 b[rt].l = l,b[rt].r = r; 6 if(l==r){ 7 b[rt].maxx = a[l];return ; 8 } 9 int mid = (l+r)>>1; 10 Build(ls),Build(rs); 11 b[rt].maxx = max(b[tl].maxx,b[tr].maxx); 12 } 13 void update(int rt,int cnt,int num){//单点修改 14 if(b[rt].l==b[rt].r){ 15 b[rt].maxx= num;return ; 16 } 17 if(cnt<=b[tl].r)update(tl,cnt,num); 18 else update(tr,cnt,num); 19 b[rt].maxx = max(b[tl].maxx,b[tr].maxx);//更新 20 } 21 int query(int rt,int l,int r){//区间查询 22 if(b[rt].l==l&&b[rt].r==r)return b[rt].maxx; 23 int mid = (b[rt].l+b[rt].r)>>1; 24 if(r<=mid)return query(tl,l,r); 25 else if(l>mid)return query(tr,l,r); 26 else return max(query(ls),query(rs)); 27 } 28 int main(){ 29 int n,m,j,num; 30 string s,q = "Q",u = "U"; 31 fio 32 while(cin>>n>>m){ 33 for(int i = 1;i <= n;++i)cin>>a[i]; 34 Build(1,1,n); 35 while(m--){ 36 cin>>s>>j>>num; 37 if(s==q)cout<<query(1,j,num)<<endl; 38 if(s==u)update(1,j,num); 39 } 40 } 41 return 0; 42 }
1 struct node{ 2 int l,r; 3 int len,mid; 4 ll num,lz; 5 }b[4*N]; 6 void build(int rt,int l,int r){ 7 b[rt].l = l;b[rt].r = r; 8 b[rt].len = r-l+1;b[rt].mid = (l+r)>>1; 9 if(l == r){ 10 b[rt].num = a[l];return ; 11 } 12 int mid = (l + r)>>1; 13 build(ls),build(rs); 14 b[rt].num = b[tl].num + b[tr].num; 15 }//构造 16 void push_down(int rt){ 17 if(b[rt].lz){ 18 b[tl].lz += b[rt].lz;b[tl].num += b[rt].lz*(b[rt].mid-b[tl].l+1); 19 b[tr].lz += b[rt].lz;b[tr].num += b[rt].lz*(b[tr].r -b[rt].mid); 20 b[rt].lz = 0; 21 } 22 }//向下更新 23 void update(int rt,int l,int r,ll num){//区间修改 24 if(b[rt].l>= l&&b[rt].r<=r){ 25 b[rt].num+=(num*b[rt].len); 26 b[rt].lz += num;return; 27 } 28 if(b[rt].r<l||b[rt].l>r)return ; 29 push_down(rt); 30 if(b[tl].r >= l)update(tl,l,r,num); 31 if(b[tr].l <= r)update(tr,l,r,num); 32 b[rt].num = b[tl].num + b[tr].num; 33 } 34 ll query(int rt,int l,int r){//区间查询 35 if(b[rt].l>r||b[rt].r<l)return 0; 36 if(b[rt].l>=l&&b[rt].r<=r)return b[rt].num; 37 push_down(rt); 38 ll s = 0; 39 if(b[tl].r>=l)s+=query(tl,l,r); 40 if(b[tr].l<=r)s+=query(tr,l,r); 41 return s; 42 } 43 44 int main() 45 { 46 //省略部分 47 build(1,1,n); 48 while(m--){ 49 cin>>s; 50 if(s==q){ 51 cin>>l>>r; 52 cout<<query(1,l,r)<<endl; 53 } 54 else{ 55 cin>>l>>r>>k; 56 update(1,l,r,k); 57 } 58 } 59 return 0; 60 }
以上是关于线段树专题的主要内容,如果未能解决你的问题,请参考以下文章