数据结构是我当年难以逾越的一道沟…
多年以后,先从最简单的线段树下手吧
写了一个 洛谷线段树的模板题 区间加 和 区间求和 很简单,算是留念吧
//
// Created by DELL on 2020/3/1.
//
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define Maxn 100005
#define LL long long
using namespace std;
struct Seg_Ment_Tree{
int l,r,lazy; LL Sum;
}tre[Maxn << 2];
void Built(int now,int l ,int r) {
tre[now].l = l,tre[now].r = r,tre[now].Sum = tre[now].lazy = 0;
if(l == r) { scanf("%lld",&tre[now].Sum); return ; }
int Mid = l + r >> 1;
Built(now << 1,l,Mid);
Built(now << 1 | 1,Mid + 1,r);
tre[now].Sum = tre[now << 1].Sum + tre[now << 1 | 1].Sum;
}
inline void Pushdown(int now) {
tre[now << 1].lazy += tre[now].lazy;
tre[now << 1 | 1].lazy += tre[now].lazy;
tre[now << 1].Sum += (tre[now << 1].r - tre[now << 1].l + 1) * tre[now].lazy;
tre[now << 1 | 1].Sum += (tre[now << 1 | 1].r - tre[now << 1 | 1].l + 1) * tre[now].lazy;
tre[now].lazy = 0;
return ;
}
void Modify(int now,int l,int r,int val){
if(l == tre[now].l && tre[now].r == r) {
tre[now].Sum += (tre[now].r - tre[now].l + 1) * val;
tre[now].lazy += val;
return ;
}
if(tre[now].lazy ) Pushdown(now);
int Mid = tre[now].l + tre[now].r >> 1;
if(l > Mid) Modify(now << 1 | 1,l,r,val);
else if(r <= Mid) Modify(now << 1,l,r,val);
else { Modify(now << 1,l,Mid,val); Modify(now << 1 | 1,Mid + 1,r,val); }
tre[now].Sum = tre[now << 1].Sum + tre[now << 1 | 1].Sum;
}
LL Query(int now,int l,int r) {
if(l == tre[now].l && tre[now].r == r) return tre[now].Sum;
int ret = 0;
if(tre[now].lazy) Pushdown(now);
int Mid = tre[now].l + tre[now].r >> 1;
if(l > Mid)return Query(now << 1|1,l,r);
else if(r <= Mid) return Query(now << 1,l,r);
else return Query(now << 1,l,Mid) + Query(now << 1 | 1,Mid + 1,r);
//return ret;
}
int main(int argc,char* argv[]) {
int val,l,r,n,m,opt; char ch;
while(scanf("%d%d",&n,&m) == 2 && n) {
Built(1,1,n);
for(int i=1; i<=m; i++) {
scanf("%d",&opt);
if(opt == 1) {
scanf("%d%d%d",&l,&r,&val);
Modify(1,l,r,val);
}
if(opt == 2) {
scanf("%d%d",&l,&r);
printf("%lld\n",Query(1,l,r));
}
}
break;
}
return 0;
}