代码比较长,还没有完全理解
https://www.luogu.com.cn/blog/pks-LOVING/senior-data-structure-qian-tan-xian-duan-shu-segment-tree
package info.frady.luogu;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
//这是一个线段树的模板题目
//对区间进行增加
//对区间进行求和
public class P3372 {
static long[] sum_tree;
static long[] tag;//延迟标记
static long[] a;
public static void main(String[] args) throws Exception{
System.setIn(new FileInputStream("C:\\Users\\86153\\Desktop\\SW\\3372\\P3372_8.in"));
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(reader.readLine());
int N=Integer.parseInt(st.nextToken());//N个数字
int M=Integer.parseInt(st.nextToken());//M次操作
int L=1;//计算保存结果需要的数组大小
while(L<N){
L=L+L;
}
sum_tree=new long[2*L];
tag=new long[2*L];
a=new long[2*L];
st=new StringTokenizer(reader.readLine());
for (int i = 1; i <=N ; i++) {
a[i]=Integer.parseInt(st.nextToken());
}
build(1,1,N);
for (int i = 0; i <M ; i++) {
st=new StringTokenizer(reader.readLine());
int o=Integer.parseInt(st.nextToken());
int a=Integer.parseInt(st.nextToken());
int b=Integer.parseInt(st.nextToken());
if(o==1){//将区间的数字都加K
int k=Integer.parseInt(st.nextToken());
update(a,b,1,N,1,k);
}else{
long v=query(a,b,1,N,1);
System.out.println(v);
}
}
reader.close();
}
static int ls(int x){//左侧子节点 左侧子节点id= id*2
return x<<1;
}
static int rs(int x) {//右侧子节点 右侧子节点id= id*2+1 由于左移完之后最后一位二进制位上一定会是 0 ,所以 |1 等价于 +1
return x<<1|1;
}
static void push_up(int p) {//父节点的值=两个子节点的值求和 维护父子节点之间的逻辑关系
sum_tree[p]=sum_tree[ls(p)]+sum_tree[rs(p)];
}
static void push_up_min(int p){//max and min
//t[p]=min(t[lc(p)],t[rc(p)]);
//t[p]=max(t[lc(p)],t[rc(p)]);
}
static void build(int p,int l,int r){//建树
tag[p]=0;
if(l==r){//如果左右区间相同,那么必然是叶子节点啦,只有叶子节点是被真实赋值的
sum_tree[p]=a[l];
return ;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
}
static void f(int p,int l,int r,long k){
tag[p]=tag[p]+k;
sum_tree[p]=sum_tree[p]+k*(r-l+1);
}
static void push_down(int p,int l,int r){
int mid=(l+r)>>1;
f(ls(p),l,mid,tag[p]);
f(rs(p),mid+1,r,tag[p]);
tag[p]=0;
}
static void update(long nl,long nr,int l,int r,int p,long k)
{
if(nl<=l&&r<=nr)
{
sum_tree[p]+=k*(r-l+1);
tag[p]+=k;
return ;
}
push_down(p,l,r);
int mid=(l+r)>>1;
if(nl<=mid)update(nl,nr,l,mid,ls(p),k);
if(nr>mid) update(nl,nr,mid+1,r,rs(p),k);
push_up(p);
}
static long query(long q_x,long q_y,int l,int r,int p){
long res=0;
if(q_x<=l&&r<=q_y)return sum_tree[p];
int mid=(l+r)>>1;
push_down(p,l,r);
if(q_x<=mid)res+=query(q_x,q_y,l,mid,ls(p));
if(q_y>mid) res+=query(q_x,q_y,mid+1,r,rs(p));
return res;
}
}