线段树&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 }

 

posted @ 2019-10-11 23:08  yya雨  阅读(156)  评论(0编辑  收藏  举报