【luogu P3372 线段树1】模板

线段树的模板题

update区间修改,query区间求和

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #define ll long long
 5 #define lson left, mid, rt<<1
 6 #define rson mid+1, right, rt<<1|1
 7 using namespace std;
 8 const int maxn = 100000;
 9 ll n, m, ans[maxn<<2],lazy[maxn<<2],tot=0,re[maxn<<2];
10 void PushUP(ll rt)
11 {
12     ans[rt] = ans[rt<<1] + ans[rt<<1|1];
13 }
14 void build(ll left, ll right, ll rt)
15 {
16     if(left == right)
17     {
18         cin>>ans[rt];
19         return;
20     }
21     ll mid = (left + right)>>1;
22     build(lson);
23     build(rson);
24     PushUP(rt);
25 }
26
27 void PushDOWN(ll rt, ll mid, ll left, ll right)
28 {
29     if(lazy[rt])
30     {
31         lazy[rt<<1]+=lazy[rt];
32         lazy[rt<<1|1]+=lazy[rt];
33         ans[rt<<1]+=(mid-left+1)*lazy[rt];
34         ans[rt<<1|1]+=(right-mid)*lazy[rt];
35         lazy[rt]=0;
36     }
37 }
38 ll query(ll l, ll r, ll left, ll right, ll rt)
39 {
40     ll res = 0;
41     if(l<=left&&r>=right)
42     {
43         return ans[rt];
44     }
45     ll mid = (left + right)>>1;
46     PushDOWN(rt,mid,left,right);
47     if(l<=mid) res += query(l,r,lson);
48     if(r>mid) res += query(l,r,rson);
49     return res;
50 }
51 void update(ll l, ll r, ll add, ll left, ll right, ll rt)
52 {
53     if(l<=left&&r>=right)
54     {
55         lazy[rt]+=add;
56         ans[rt]+=add*(right-left+1);
57         return;
58     }
59     ll mid = (left+right)>>1;
60     PushDOWN(rt,mid,left,right);
61     if(l<=mid) update(l,r,add,lson);
62     if(r>mid)  update(l,r,add,rson);
63     PushUP(rt);
64 }
65
66 int main()
67 {
68     cin.sync_with_stdio(false);
69     cin>>n>>m;
70     ll p,x,y,k;
71     build(1,n,1);
72     while(m--)
73     {
74         cin>>p;
75         if(p==1)
76         {
77             cin>>x>>y>>k; update(x,y,k,1,n,1);
78         }
79         if(p==2)
80         {
81             tot++;
82             cin>>x>>y;    cout<<query(x,y,1,n,1);
83         }
84     }
85     return 0;
86 }

原文地址:https://www.cnblogs.com/MisakaAzusa/p/8485181.html

时间: 2024-08-29 05:34:50

【luogu P3372 线段树1】模板的相关文章

洛谷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

线段树--线段树【模板1】P3372

题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式 输出包含若干行整数,即为所有操作2

敌兵布阵 (线段树简单模板题)

https://vjudge.net/contest/318019#problem C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向

线段树---分析 &amp;&amp; 模板总结

线段树:(转) 数据结构专题---线段树:http://blog.csdn.net/metalseed/article/details/8039326 线段树总结:http://blog.csdn.net/shiqi_614/article/details/8228102 概述: 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b

线段树lazy模板 luogu3372

线段树写得很少,这么基本的算法还是要会的-- #include<bits/stdc++.h> using namespace std; inline long long read() { long long x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-') f = -1;ch = getchar(); } while (ch >= '0'&&ch <=

线段树1模板

传送门:线段树1 1 #include<cstdio> 2 3 const int MAXN = 200000*4; 4 typedef long long LL; 5 6 int n,m,p,u,v; 7 long long x,Segment_Tree[MAXN],Add[MAXN]; 8 9 template <typename Type> inline void Read(Type &in){ 10 Type f=1;char ch=getchar(); 11 fo

BZOJ4034 树上操作(树剖 线段树大模板)

BZOJ4034 long long 是大坑点 貌似long long 跟int 乘起来会搞事情?... A了这题线段树和树剖的基础OK 嘛 重点过掉的还是线段树区间更新的lazy tag吧 #include<cstdio> #include<cstring> #define N 100001 using namespace std; struct ed{ int nxt,to; }e[N*2]; int ne=0,head[N]; long long int w0[N]; str

Pascal 线段树 lazy-tag 模板

先说下我的代码风格(很丑,勿喷) maxn表示最大空间的四倍 tree数组表示求和的线段树 delta表示增减的增量标记 sign表示覆盖的标记 delta,sign实际上都是lazy标志 pushdown表示标记下传 pushup表示标记上传(即求和,区间最值) update表示数据更新 线段树(segment tree)是一种特别有用的数据结构,我们在维护区间各种信息的时候它就是利器.可能读者嫌线段树代码太长,不想写,而树状数组代码简洁易于便携,但是我在这里想说,线段树能做到的很多东西树状数

luogu 3582 线段树

线段树内存下mx[k]的值是动态的1-i这个区间的贡献答案 实际上点存的就是区间答案,但用max是为了求最大区间答案(有可能虽然贡献被消除但后来有更大的贡献填补答案空缺) #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define dec(i,x,y) for(register int i=x;i>=y;i--) #define LL long long #define In f