线段树专题

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 }

以上是关于线段树专题的主要内容,如果未能解决你的问题,请参考以下文章

线段树专题

线段树专题

非递归线段树专题

线段树专题 POJ3468 A Simple Problem with Integers

线段树专题—HDU1698 Just a Hook

线段树专题(不定期更新)