线段树模板

Posted 不可爱的小可爱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。

1、求区间和

技术分享
 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 const int maxn=50000+5;
 5 int a[maxn];
 6 struct Node
 7 {
 8     int l,r,sum;
 9 } node[maxn<<2];
10 
11 //参数含义:节点区间,节点编号
12 void InitTree(int l,int r,int k)
13 {
14     node[k].r=r;//节点k的右子树
15     node[k].l=l;
16     node[k].sum=0;//权值
17     if(l==r)//到达叶子节点
18     {
19         node[k].sum=a[r];
20         return;
21     }
22     int mid=(l+r)>>1;
23     InitTree(l,mid,k<<1);//递归建左子树
24     InitTree(mid+1,r,k<<1|1);//递归建右子树
25 
26     node[k].sum=node[k<<1].sum+node[k<<1|1].sum;
27     //父节点的值为两子节点值的和
28     //此为线段树的核心所在,求最值修改这一句即可
29 }
30 void UpdateTree(int l,int r,int k,int sum)
31 {
32     if(node[k].l==l&&node[k].r==r)
33     {
34         node[k].sum+=sum;
35         return;
36     }
37     int mid=(node[k].l+node[k].r)>>1;
38     if(l>mid)
39         UpdateTree(l,r,k<<1|1,sum);//更新下一层的右子树
40     else
41         UpdateTree(l,r,k<<1,sum);
42 
43     node[k].sum=node[k<<1].sum+node[k<<1|1].sum;
44     //注意:每次更新后也要更新父节点的值
45 }
46 //查询l到r的k
47 int SearchTree(int l,int r,int k)
48 {
49     if(node[k].l==l&&node[k].r==r)
50     {
51         return node[k].sum;
52     }
53     int mid=(node[k].l+node[k].r)>>1;
54     if(l>mid)
55     {
56         return SearchTree(l,r,k<<1|1);//查询右子树
57     }
58     else if(r<=mid)
59     {
60         return SearchTree(l,r,k<<1);
61     }
62     else
63     {
64         //查询区间横跨左右子树,两棵子树一起查询
65         return SearchTree(mid+1,r,k<<1|1)+SearchTree(l,mid,k<<1);
66     }
67 }
68 int main()
69 {
70     int T,kase=0;
71     cin>>T;
72     while(T--)
73     {
74         printf("Case %d:\n",++kase);
75         int n,x,y;
76         scanf("%d",&n);
77         for(int i=1;i<=n;i++)
78         {
79             scanf("%d",&a[i]);
80         }
81         InitTree(1,n,1);
82         char ch[10];
83         while(scanf("%s",ch))
84         {
85             if(ch[0]==E)
86                 break;
87             scanf("%d%d",&x,&y);
88             if(ch[0]==A)
89                 UpdateTree(x,x,1,y);
90             else if(ch[0]==S)
91                 UpdateTree(x,x,1,-y);
92             else if(ch[0]==Q)
93                 cout<<SearchTree(x,y,1)<<endl;
94         }
95     }
96     return 0;
97 }
区间和

2、求区间最大值

技术分享
 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 const int maxn=200000+5;
 5 int a[maxn];
 6 struct Node
 7 {
 8     int l,r,sum;
 9 } node[maxn<<2];
10 
11 //参数含义:节点区间,节点编号
12 void InitTree(int l,int r,int k)
13 {
14     node[k].r=r;//节点k的右子树
15     node[k].l=l;
16     node[k].sum=0;//权值
17     if(l==r)//到达叶子节点
18     {
19         node[k].sum=a[r];
20         return;
21     }
22     int mid=(l+r)>>1;
23     InitTree(l,mid,k<<1);//递归建左子树
24     InitTree(mid+1,r,k<<1|1);//递归建右子树
25 
26     node[k].sum=max(node[k<<1].sum,node[k<<1|1].sum);
27     //父节点的值为两子节点值的和
28     ///此为线段树的核心所在,求最值修改这一句即可
29 }
30 void UpdateTree(int l,int r,int k,int sum)
31 {
32     if(node[k].l==l&&node[k].r==r)
33     {
34         node[k].sum=sum;
35         return;
36     }
37     int mid=(node[k].l+node[k].r)>>1;
38     if(l>mid)
39         UpdateTree(l,r,k<<1|1,sum);//更新下一层的右子树
40     else
41         UpdateTree(l,r,k<<1,sum);
42 
43     node[k].sum=max(node[k<<1].sum,node[k<<1|1].sum);
44     //注意:每次更新后也要更新父节点的值
45 }
46 //查询l到r的k
47 int SearchTree(int l,int r,int k)
48 {
49     if(node[k].l==l&&node[k].r==r)
50     {
51         return node[k].sum;
52     }
53     int mid=(node[k].l+node[k].r)>>1;
54     if(l>mid)
55     {
56         return SearchTree(l,r,k<<1|1);//查询右子树
57     }
58     else if(r<=mid)
59     {
60         return SearchTree(l,r,k<<1);
61     }
62     else
63     {
64         //查询区间横跨左右子树,两棵子树一起查询
65         return max(SearchTree(mid+1,r,k<<1|1),SearchTree(l,mid,k<<1));
66     }
67 }
68 int main()
69 {
70     int n,m;
71     while(scanf("%d%d",&n,&m)!=EOF)
72     {
73         int x,y;
74         for(int i=1;i<=n;i++)
75         {
76             scanf("%d",&a[i]);
77         }
78         InitTree(1,n,1);
79         char ch;
80         while(m--)
81         {
82             getchar();
83             scanf("%c",&ch);
84             scanf("%d%d",&x,&y);
85             if(ch==U)
86                 UpdateTree(x,x,1,y);
87             else if(ch==Q)
88                 printf("%d\n",SearchTree(x,y,1));
89         }
90     }
91     return 0;
92 }
求最大值

 

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

线段树模板整理

线段树模板总结

线段树模板

模板线段树-单点修改,区间查询

P3834 模板可持久化线段树 1(主席树)

模板 线段树(部分功能)