#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[114514];
int sgt[414514];
int lc[414514],rc[414514];
int tag[414514];
int build(int l,int r,int i){
lc[i]=l;
rc[i]=r;
if(l==r){
sgt[i]=a[l];
return a[l];
}
int m=(l+r)>>1;
sgt[i]=build(l,m,i<<1)+build(m+1,r,(i<<1)|1);
return sgt[i];
}
void pushdown(int l,int r,int i,int x){
if(l==lc[i]&&r==rc[i]){
tag[i]+=(r-l+1)*x;
sgt[i]+=tag[i];
return;
}
int m=rc[i*2];
if(l<=m){
pushdown(l,m,i<<1,x);
}
if(r>=m+1){
pushdown(m+1,r,(i<<1)|1,x);
}
}
int query(int l,int r,int i){
if(l==lc[i]&&r==rc[i]){
return sgt[i];
}
int m=rc[i*2];
if(tag[i]){
sgt[i]+=tag[i];
pushdown(lc[i<<1],rc[i<<1],i<<1,tag[i]/(rc[i]-lc[i]+1));
pushdown(lc[(i<<1)|1],rc[(i<<1)|1],(i<<1)|1,tag[i]/(rc[i]-lc[i]+1));
tag[i]=0;
}
int sum=0;
if(l<=m){
sum+=query(l,m,i<<1);
}
if(r>=m+1){
sum+=query(m+1,r,(i<<1)|1);
}
return sum;
}
main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int t=build(1,n,1);
for(int i=1;i<=m;i++){
int op,l,r;
cin>>op>>l>>r;
if(op==1){
int x;
cin>>x;
pushdown(l,r,1,x);
}
else{
cout<<query(l,r,1)<<endl;
}
}
for(int i=1;i<=n*4;i++){
cout<<i<<" "<<lc[i]<<" "<<rc[i]<<" "<<tag[i]<<" "<<sgt[i]<<endl;
}
}
我估计是犯了个唐诗的错误,但我没看出来
O.O为什么姐姐的写法这么独特(挠头
@little_zxh_qwq pushdown 不能这么乱写啊,要和 Update 分开
什么逆天写法,把 update 和 pushdown 弄在一起,又在 query 调用 pushdown,好奇特
@Gcc_Gdb_7_8_1 理解不了,能说的更详细一点吗
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[114514];
int sgt[414514];
int lc[414514],rc[414514];
int tag[414514];
int build(int l,int r,int i){
lc[i]=l;
rc[i]=r;
if(l==r){
sgt[i]=a[l];
return a[l];
}
int m=(l+r)>>1;
sgt[i]=build(l,m,i<<1)+build(m+1,r,(i<<1)|1);
return sgt[i];
}
void pushdown(int l,int r,int i,int x){
if(l==lc[i]&&r==rc[i]){ //姐姐这里它不一定就是一整段区间刚好配上的,线段树是要把目标区间分成许多个小区间去操作的
tag[i]+=(r-l+1)*x;
sgt[i]+=tag[i];
return;
}
int m=rc[i*2];
if(l<=m){
pushdown(l,m,i<<1,x);
}
if(r>=m+1){
pushdown(m+1,r,(i<<1)|1,x);
}
}
int query(int l,int r,int i){
if(l==lc[i]&&r==rc[i]){
return sgt[i];
}
int m=rc[i*2];
if(tag[i]){
sgt[i]+=tag[i];
pushdown(lc[i<<1],rc[i<<1],i<<1,tag[i]/(rc[i]-lc[i]+1));
pushdown(lc[(i<<1)|1],rc[(i<<1)|1],(i<<1)|1,tag[i]/(rc[i]-lc[i]+1));
tag[i]=0;
}
int sum=0;
if(l<=m){
sum+=query(l,m,i<<1);
}
if(r>=m+1){
sum+=query(m+1,r,(i<<1)|1);
}
return sum;
}
main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int t=build(1,n,1);
for(int i=1;i<=m;i++){
int op,l,r;
cin>>op>>l>>r;
if(op==1){
int x;
cin>>x;
pushdown(l,r,1,x);
}
else{
cout<<query(l,r,1)<<endl;
}
}
for(int i=1;i<=n*4;i++){
cout<<i<<" "<<lc[i]<<" "<<rc[i]<<" "<<tag[i]<<" "<<sgt[i]<<endl;
}
}
@Gcc_Gdb_7_8_1query的pushdown不会下传啊,在下一层就停下了
pushdown 递归调用,那我每次都在根节点打 tag 你不炸了吗