搬运——线段树模板

最近各种线段树,然后一直用HH模板!然后老是写不出!

与之搬运过来!

线段树功能:update:单点增减 query:区间求和

#include <cstdio>

#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 55555;
int sum[maxn<<2];
void PushUP(int rt) {
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void build(int l,int r,int rt) {
	if (l == r) {
		scanf("%d",&sum[rt]);
		return ;
	}
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
	PushUP(rt);
}
void update(int p,int add,int l,int r,int rt) {
	if (l == r) {
		sum[rt] += add;
		return ;
	}
	int m = (l + r) >> 1;
	if (p <= m) update(p , add , lson);
	else update(p , add , rson);
	PushUP(rt);
}
int query(int L,int R,int l,int r,int rt) {
	if (L <= l && r <= R) {
		return sum[rt];
	}
	int m = (l + r) >> 1;
	int ret = 0;
	if (L <= m) ret += query(L , R , lson);
	if (R > m) ret += query(L , R , rson);
	return ret;
}
int main() {
	int T , n;
	scanf("%d",&T);
	for (int cas = 1 ; cas <= T ; cas ++) {
		printf("Case %d:\n",cas);
		scanf("%d",&n);
		build(1 , n , 1);
		char op[10];
		while (scanf("%s",op)) {
			if (op[0] == ‘E‘) break;
			int a , b;
			scanf("%d%d",&a,&b);
			if (op[0] == ‘Q‘) printf("%d\n",query(a , b , 1 , n , 1));
			else if (op[0] == ‘S‘) update(a , -b , 1 , n , 1);
			else update(a , b , 1 , n , 1);
		}
	}
	return 0;
}

  线段树功能:update:单点替换 query:区间最值

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 #define lson l , m , rt << 1
 6 #define rson m + 1 , r , rt << 1 | 1
 7 const int maxn = 222222;
 8 int MAX[maxn<<2];
 9 void PushUP(int rt) {
10     MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
11 }
12 void build(int l,int r,int rt) {
13     if (l == r) {
14         scanf("%d",&MAX[rt]);
15         return ;
16     }
17     int m = (l + r) >> 1;
18     build(lson);
19     build(rson);
20     PushUP(rt);
21 }
22 void update(int p,int sc,int l,int r,int rt) {
23     if (l == r) {
24         MAX[rt] = sc;
25         return ;
26     }
27     int m = (l + r) >> 1;
28     if (p <= m) update(p , sc , lson);
29     else update(p , sc , rson);
30     PushUP(rt);
31 }
32 int query(int L,int R,int l,int r,int rt) {
33     if (L <= l && r <= R) {
34         return MAX[rt];
35     }
36     int m = (l + r) >> 1;
37     int ret = 0;
38     if (L <= m) ret = max(ret , query(L , R , lson));
39     if (R > m) ret = max(ret , query(L , R , rson));
40     return ret;
41 }
42 int main() {
43     int n , m;
44     while (~scanf("%d%d",&n,&m)) {
45         build(1 , n , 1);
46         while (m --) {
47             char op[2];
48             int a , b;
49             scanf("%s%d%d",op,&a,&b);
50             if (op[0] == ‘Q‘) printf("%d\n",query(a , b , 1 , n , 1));
51             else update(a , b , 1 , n , 1);
52         }
53     }
54     return 0;
55 }

线段树功能:update:成段增减 query:区间求和

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 #define lson l , m , rt << 1
 6 #define rson m + 1 , r , rt << 1 | 1
 7 #define LL long long
 8 const int maxn = 111111;
 9 LL add[maxn<<2];
10 LL sum[maxn<<2];
11 void PushUp(int rt) {
12     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
13 }
14 void PushDown(int rt,int m) {
15     if (add[rt]) {
16         add[rt<<1] += add[rt];
17         add[rt<<1|1] += add[rt];
18         sum[rt<<1] += add[rt] * (m - (m >> 1));
19         sum[rt<<1|1] += add[rt] * (m >> 1);
20         add[rt] = 0;
21     }
22 }
23 void build(int l,int r,int rt) {
24     add[rt] = 0;
25     if (l == r) {
26         scanf("%lld",&sum[rt]);
27         return ;
28     }
29     int m = (l + r) >> 1;
30     build(lson);
31     build(rson);
32     PushUp(rt);
33 }
34 void update(int L,int R,int c,int l,int r,int rt) {
35     if (L <= l && r <= R) {
36         add[rt] += c;
37         sum[rt] += (LL)c * (r - l + 1);
38         return ;
39     }
40     PushDown(rt , r - l + 1);
41     int m = (l + r) >> 1;
42     if (L <= m) update(L , R , c , lson);
43     if (m < R) update(L , R , c , rson);
44     PushUp(rt);
45 }
46 LL query(int L,int R,int l,int r,int rt) {
47     if (L <= l && r <= R) {
48         return sum[rt];
49     }
50     PushDown(rt , r - l + 1);
51     int m = (l + r) >> 1;
52     LL ret = 0;
53     if (L <= m) ret += query(L , R , lson);
54     if (m < R) ret += query(L , R , rson);
55     return ret;
56 }
57 int main() {
58     int N , Q;
59     scanf("%d%d",&N,&Q);
60     build(1 , N , 1);
61     while (Q --) {
62         char op[2];
63         int a , b , c;
64         scanf("%s",op);
65         if (op[0] == ‘Q‘) {
66             scanf("%d%d",&a,&b);
67             printf("%lld\n",query(a , b , 1 , N , 1));
68         } else {
69             scanf("%d%d%d",&a,&b,&c);
70             update(a , b , c , 1 , N , 1);
71         }
72     }
73     return 0;
74 }
时间: 2024-12-21 01:55:06

搬运——线段树模板的相关文章

线段树模板(结构体)

线段树研究了两天了,总算有了点眉目,今天也把落下的题,补了一下. 贴一份线段树模板 线段树的特点: 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 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的