线段树&RMQ
RMQ模板
详解见:https://blog.csdn.net/Sclong0218/article/details/97036282
模板:
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N=1e5+10;
4 int dp[N][64];
5 int arr[N];
6 void RMQ(int num) {
7 for(int i=1;i<=num;i++){
8 dp[i][0]=arr[i];
9 }
10 for(int j = 1; (1<<j) <= num; j++)
11 for(int i = 1; i+(1<<j)-1 <= num; i++)
12 dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
13 }
14
15 int query(int l, int r)
16 {
17 int k = log(r-l+1) / log(2);
18 return max(dp[l][k], dp[r - (1<<k) + 1][k]);
19 }
20 int main(){
21 int n,k,l,r;
22 cin>>n;
23 for(int i=1;i<=n;i++){
24 scanf("%d",arr+i);
25 }
26 RMQ(n);
27 cin>>k;
28 for(int i=0;i<k;i++){
29 scanf("%d%d",&l,&r);
30 printf("%d\n",query(l+1,r+1));
31 }
32
33 return 0;
34 }
线段树模板:
单点修改
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N=1e6;
5 int arr[N];
6 ll ans[N];
7 void build_tree(int node,int start,int end){
8 if(start==end){
9 ans[node]=arr[end];
10 return ;
11 }
12 int left_node=2*node+1;
13 int right_node=2*node+2;
14 int mid=(start+end)>>1;
15 build_tree(left_node,start,mid);
16 build_tree(right_node,mid+1,end);
17 ans[node]=ans[left_node]+ans[right_node];
18 }
19
20 void update(int node,int start,int end,int p,int v){
21 if(start==end){
22 ans[node]=v;
23 arr[p]=v;
24 return ;
25 }
26 int mid=(start+end)>>1;
27 int left_node=2*node+1;
28 int right_node=2*node+2;
29 if(p<=mid){
30 update(left_node,start,mid,p,v);
31 }
32 else{
33 update(right_node,mid+1,end,p,v);
34 }
35 ans[node]=ans[left_node]+ans[right_node];
36 }
37
38 ll query(int node,int start,int end,int l,int r){
39 if(r<start||l>end){
40 return 0;
41 }
42 else if(start>=l&&end<=r){
43 return ans[node];
44 }
45 else if(start==end){
46 return ans[node];
47 }
48 int mid=(start+end)>>1;
49 int left_node=2*node+1;
50 int right_node=2*node+2;
51 ll sum_left=query(left_node,start,mid,l,r);
52 ll sum_right=query(right_node,mid+1,end,l,r);
53 return sum_left+sum_right;
54 }
55 int main(){
56 int n,l,r;
57 cin>>n;
58 for(int i=0;i<n;i++){
59 scanf("%d",arr+i);
60 }
61 build_tree(0,0,n-1);
62 cin>>n;
63 for(int i=0;i<n;i++){
64 scanf("%d %d",&l,&r);
65 cout<<query(0,0,n-1,l,r)<<endl;
66 }
67 return 0;
68 }
区间修改:
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N=1e6;
5 ll arr[N];
6 ll ans[N<<1];
7 ll lazy[N<<1];
8 void build(ll p,ll l,ll r){
9 ll mid;
10 if(l==r){
11 ans[p]=arr[l];
12 return ;
13 }
14 mid=(l+r)>>1;
15 build(p<<1,l,mid);
16 build(p<<1|1,mid+1,r);
17 ans[p]=ans[p<<1]+ans[p<<1|1];
18 return ;
19 }
20 void push_down(ll p,ll l,ll r){
21 if(!lazy[p])
22 return ;
23 ll mid=(l+r)>>1;
24 lazy[p<<1]+=lazy[p];
25 lazy[p<<1|1]+=lazy[p];
26 ans[p<<1]+=(lazy[p]*(mid-l+1));
27 ans[p<<1|1]+=(lazy[p]*(r-mid));
28 lazy[p]=0;
29 return ;
30 }
31 void update(ll p,ll l,ll r,ll nl,ll nr,ll k){
32 if(r<nl||l>nr)
33 return ;
34 if(nl<=l&&nr>=r){
35 lazy[p]+=k;
36 ans[p]+=((r-l+1)*k);
37 return ;
38 }
39 ll mid=(l+r)>>1;
40 push_down(p,l,r);
41 update(p<<1,l,mid,nl,nr,k);
42 update(p<<1|1,mid+1,r,nl,nr,k);
43 ans[p]=ans[p<<1]+ans[p<<1|1];
44 return ;
45 }
46 ll query(ll p,ll l,ll r,ll nl,ll nr){
47 if(r<nl||l>nr)
48 return 0;
49 if(nl<=l&&nr>=r)
50 return ans[p];
51 push_down(p,l,r);
52 ll mid=(l+r)>>1;
53 return query(p<<1,l,mid,nl,nr)+query(p<<1|1,mid+1,r,nl,nr);
54 }
55 int main(){
56 ll n,m,x,q,p,y;
57 scanf("%lld%lld",&n,&m);
58 for(ll i=1;i<=n;i++)
59 scanf("%lld",&arr[i]);
60 build(1,1,n);
61 for(ll i=1;i<=m;i++){
62 scanf("%lld%lld%lld",&x,&p,&q);
63 if(x==1){
64 scanf("%lld",&y);
65 update(1,1,n,p,q,y);
66 }
67 else printf("%lld\n",query(1,1,n,p,q));
68 }
69 return 0;
70 }