线段树模板(待补充)

先放一个吧,过两天在写几个补充完整。

区间求最值:

 1 #include<iostream>
 2 #define LC(a)  ((a<<1))
 3 #define RC(a)  ((a<<1)+1)
 4 #define MID(a,b) ((a+b)>>1)
 5 using namespace std;
 6 typedef long long ll;
 7 const int N=1e4*4;
 8
 9 ll mmin,mmax;
10
11 struct node{
12     ll l,r;
13     ll mmin,mmax;
14 }tree[N];
15
16 ll num[N];
17
18 void pushup(ll p)
19 {
20     tree[p].mmin=min(tree[LC(p)].mmin, tree[RC(p)].mmin);
21     tree[p].mmax=max(tree[LC(p)].mmax,tree[RC(p)].mmax);
22 }
23
24 void build(ll p,ll l,ll r){
25     tree[p].l=l;
26     tree[p].r=r;
27     tree[p].mmax=0;
28     tree[p].mmin=1e10;
29     if(l==r){
30         //单点最大最小值就是本身
31         tree[p].mmax=tree[p].mmin=num[l];
32         return;
33     }
34     build(LC(p),l,MID(l,r));
35     build(RC(p),MID(l,r)+1,r);
36     pushup(p);//自底向上推
37 }
38
39 void updata(ll p,ll l,ll r,ll num){
40     //不在更新区域内
41     if(r<tree[p].l||l>tree[p].r)
42         return;
43     //在更新区域内
44     if(l<=tree[p].l&&r>=tree[p].r){
45         tree[p].mmin=tree[p].mmax=num;
46         return;
47     }
48     updata(LC(p),l,r,num);
49     updata(RC(p),l,r,num);
50     pushup(p);
51 }
52
53 void query(ll p,ll l,ll r){
54     //不在更新区域内
55     if(r<tree[p].l||l>tree[p].r)
56         return;
57     //在更新区域内
58     if(l<=tree[p].l&&r>=tree[p].r){
59         mmin=min(tree[p].mmin,mmin);
60         mmax=max(tree[p].mmax,mmax);
61         return;
62     }
63     query(LC(p),l,r);
64     query(RC(p),l,r);
65 }
66
67 int main(){
68     int t;
69     cin>>t;
70     while(t--){
71         int n,q;
72         cin>>n>>q;
73         for(int i=1;i<=n;i++){
74             cin>>num[i];
75         }
76         //建树
77         build(1,1,n);
78         for(int i=1;i<=q;i++){
79             int p;
80             cin>>p;
81             if(p==1){
82                 ll l,r;
83                 cin>>l>>r;
84                 //初始化最大最小值
85                 mmin=1e18;
86                 mmax=0;
87                 query(1,l,r);
88                 //最大最小值差
89                 cout<<mmax-mmin<<endl;
90             }
91             else{
92                 ll idx,num;
93                 cin>>idx>>num;
94                 //用num替换第idx个点的值
95                 updata(1,idx,idx,num);
96             }
97         }
98     }
99 }

相关题目:

① NOJ1680,单点修改求区间最值,模板题

https://ac.2333.moe/Problem/view.xhtml?id=1680

时间: 2024-10-12 03:00:30

线段树模板(待补充)的相关文章

线段树模板(结构体)

线段树研究了两天了,总算有了点眉目,今天也把落下的题,补了一下. 贴一份线段树模板 线段树的特点: 1. 每一层都是区间[a, b]的一个划分,记 L = b - a 2. 一共有log2L层 3. 给定一个点p,从根到叶子p上的所有区间都包含点p,且其他区间都不包含点p. 4. 给定一个区间[l; r],可以把它分解为不超过2log2 L条不相交线段的并. 总结来说:线段树最近本的应用是4点: 1.单点更新:单点替换.单点增减 2.单点询问 3.区间询问:区间之和.区间最值 4.区间更新:区间

[ACM] 线段树模板

#include<iostream> #include<cmath> using namespace std; #define maxn 200005 class Node{ public: int l,r; int add;//附加值 int sum; }node[maxn]; int getRight(int n){//获得满足2^x>=n的最小x[从0层开始,给编号获得层数] return ceil(log10(n*1.0)/log10(2.0)); } void bu

[POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using namespace std; int n,q,tot,a[110000]; in

hdu 4819 二维线段树模板

/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 1010; int N, Q; struct Nodey { int l, r; int Max, Min; }; int locx[MAXN], l

【HDU 4819】Mosaic 二维线段树模板

二维线段树的模板题,和一维一样的思路,更新的时候注意一下细节. 存模板: /* 二维线段树模板整理 */ #include<cstdio> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) const int maxn = 805; const int INF = (1 << 30); int n; int posX[max

LA 2191电位计(线段树模板题)

线段树模板题,没啥好说的.....注意输出是case之间空一行就行.........之前一直没注意,一直wa 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #includ

洛谷P3372线段树模板1——线段树

题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cstdio> using namespace std; long long n,m,a[100005],ct; struct N{ long long lazy,sum; long long ls,rs; }p[200005]; void pushdown(long long cur,long long l

P3373 线段树模板

好,这是一个线段树模板. 1 #include <cstdio> 2 using namespace std; 3 const long long int N=1000010; 4 long long int sum[N],tag1[N],tag2[N],mo; 5 6 void build(int l,int r,int o) 7 { 8 tag1[o]=1; 9 if(l==r) 10 { 11 scanf ("%d",&sum[o]); 12 return;

线段树模板hdu 1754:I Hate It

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 100523    Accepted Submission(s): 37845 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的

POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120   Accepted: 43425 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type o