codevs 1082 线段树:区间更新,区间求和
程序员文章站
2024-01-12 16:34:46
...
codevs 1082
线段树:区间更新,区间求和
重点在于lazy的使用
与单点查询不同的是在更新和查询时都需要pushdown(下放lazy)
#include <iostream>
#include <cstdio>
#include <cstring>
#define lson u << 1,l,mid
#define rson u << 1 | 1,mid + 1,r
#define ll long long
using namespace std;
const int maxn = 200000 + 5;
int n,q,tt,a,b,c;
struct node
{
ll sum,lazy;
}t[maxn << 2];
void pushup(int u){ t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;}
void pushdown(int u,int m)//下放lazy
{
if(t[u].lazy)
{
t[u << 1].lazy += t[u].lazy;
t[u << 1 | 1].lazy += t[u].lazy;
t[u << 1].sum += (m - (m >> 1)) * t[u].lazy;
t[u << 1 | 1].sum += (m >> 1) * t[u].lazy;
t[u].lazy = 0;
}
}
void build(int u,int l,int r)
{
t[u].lazy = 0;
if(l == r)
{
scanf("%lld",&t[u].sum);
return;
}
int mid = (l + r) >> 1;
build(lson); build(rson);
pushup(u);
}
void update(int u,int l,int r,int a,int b,int c)
{
if(a <= l && r <= b)
{
t[u].lazy += c;//更新lazy标记
t[u].sum += (r - l + 1) * c;
return;
}
int mid = (l + r) >> 1;
pushdown(u,r - l + 1);//下放lazy
if(a <= mid) update(lson,a,b,c);
if(mid < b) update(rson,a,b,c);
pushup(u);
}
ll query(int u,int l,int r,int a,int b)
{
if(a <= l && r <= b) return t[u].sum;
int mid = (l + r) >> 1;
pushdown(u,r - l + 1);//下放lazy
ll ans = 0;
if(a <= mid) ans += query(lson,a,b);
if(mid < b) ans += query(rson,a,b);
return ans;
}
int main()
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&q);
for(int i = 1; i <= q; ++i)
{
scanf("%d",&tt);
if(tt == 1)
{
scanf("%d%d%d",&a,&b,&c);
update(1,1,n,a,b,c);
}
else
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(1,1,n,a,b));
}
}
return 0;
}
上一篇: 如何将本地项目push到GitHub
下一篇: 如何将本地文件push到github上?
推荐阅读
-
codevs 1082 线段树:区间更新,区间求和
-
NEFU 1111 线段树区间更新+懒惰标记相关介绍
-
洛谷-P3372-线段树 1(区间修改,区间求和)
-
【线段树-单点更新区间最大值】hdu 1754 - I Hate It
-
ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study(线段树区间求和)
-
HDU1698 Just a Hook 线段树区间更新
-
HDU1698 Just a Hook 线段树区间更新
-
HDU1698——Just a Hook(线段树区间修改,区间求和)
-
HDU1698 Just a Hook (简单的区间更新线段树)
-
poj3468A Simple Problem with Integers解题报告(线段树成段增减 & 区间求和)