社区讨论
线段树求教!!!
P3372【模板】线段树 1参与者 3已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mi6yh70h
- 此快照首次捕获于
- 2025/11/20 12:53 4 个月前
- 此快照最后确认于
- 2025/11/20 12:53 4 个月前
BigYellowDog
按着花姐的题解写,崩了,求助
两个小时找不出问题,qwq,hlep
CPP#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define N 100002
#define ll long long
#define LS rt<<1
#define RS rt<<1|1
using namespace std;
void get(ll &x)
{
char c = getchar(); x = 0;
while(c < '0' || c > '9') c = getchar();
while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}
void put(ll x)
{
ll num = 0; char c[15];
while(x) c[++num] = (x%10)+48, x /= 10;
while(num) putchar(c[num--]);
putchar('\n');
}
ll a[N];
struct tree{ll l,r,val,lazy;}tr[N<<1];
void build(ll rt,ll l,ll r)
{
tr[rt].l=l,tr[rt].r=r,tr[rt].lazy=0;
if(l==r)
{
tr[rt].val=a[l];
return;
}
ll mid=(l+r)>>1;
build(LS,l,mid);
build(RS,mid+1,r);
tr[rt].val=tr[LS].val+tr[RS].val;
}
void change(ll rt,ll l,ll r,ll delta) //这才是落实到点上的啊
{
tr[rt].lazy+=delta;
tr[rt].val+=(r-l+1)*delta; //千万不能tr[rt].l tr[rt].r
//区间修改 l,r是更新的区间
}
void push_down(ll rt,ll l,ll r)
{
ll mid=(l+r)>>1;
change(LS,l,mid,tr[rt].lazy);
change(RS,mid+1,r,tr[rt].lazy);
tr[rt].lazy=0;
}
void update(ll rt,ll l,ll r,ll delta)
{
if(l>=tr[rt].l&&r<=tr[rt].r)
{
change(rt,l,r,delta);
return;
}
push_down(rt,tr[rt].l,tr[rt].r);
ll mid=(l+r)>>1;
if(l<=mid) update(LS,l,mid,delta);
if(r>mid) update(RS,mid+1,r,delta);
tr[rt].val=tr[LS].val+tr[RS].val;
}
ll find(ll rt,ll l,ll r)
{
if(l>=tr[rt].l&&r<=tr[rt].r)
return tr[rt].val;
ll sum=0;
push_down(rt,l,r);
ll mid=(l+r)>>1;
if(l<=mid) sum+=find(LS,l,r);
if(r>mid) sum+=find(RS,l,r);
return sum;
}
ll n,m;
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
get(n),get(m);
for(ll i=1;i<=n;++i)
get(a[i]);
build(1,1,n);
ll x,y,type,k;
while(m--)
{
get(type),get(x),get(y);
if(type==1)
{
get(k);
update(1,x,y,k);
}
else
if(type==2) put(find(1,x,y));
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...