## LYXin's Blog

Here I stand. And here I'll stay.

# 线段树

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 105;

int a[maxn];
int add[maxn << 2], col[maxn << 2];
int minv[maxn << 2], maxv[maxn << 2], sum[maxn << 2];

void maintain(int o, int L, int R)
{
if(L >= R) return ;
int lc = o << 1, rc = o << 1 | 1;
sum[o] = sum[lc] + sum[rc];
maxv[o] = max(maxv[lc], maxv[rc]);
minv[o] = min(minv[lc], minv[rc]);
}

void pushdown(int o, int L, int R)
{
if(L >= R) return ;
int M = (L + R) >> 1, lc = o << 1, rc = o << 1 | 1;
if(col[o])
{
col[lc] = col[rc] = col[o];
sum[lc] = col[o] * (M-L+1);
sum[rc] = col[o] * (R-M);
maxv[lc] = maxv[rc] = minv[lc] = minv[rc] = col[o];
col[o] = 0;
}
{
}
}

int op, qv, _sum, _max, _min;

void update(int o, int L, int R, int ql, int qr)
{
if(L == ql && qr == R)
{
{
maxv[o] += qv;
minv[o] += qv;
sum[o] += qv * (R-L+1);
}
else//set
{
col[o] = maxv[o] = minv[o] = qv;
sum[o] = qv * (R-L+1);
}
}
else
{
pushdown(o, L, R);
int M = (L + R) >> 1;
if(qr <= M) update(o << 1, L, M, ql, qr);
else if(M < ql) update(o << 1 | 1, M+1, R, ql, qr);
else
{
update(o << 1, L, M, ql, M);
update(o << 1 | 1, M+1, R, M+1, qr);
}
maintain(o, L, R);
}
}

void query(int o, int L, int R, int ql, int qr)
{
if(L == ql && qr == R)
{
_sum += sum[o];
_max = max(_max, maxv[o]);
_min = min(_min, minv[o]);
}
else
{
pushdown(o, L, R);
int M = (L + R) >> 1;
if(qr <= M) query(o << 1, L, M, ql, qr);
else if(M < ql) query(o << 1 | 1, M+1, R, ql, qr);
else
{
query(o << 1, L, M, ql, M);
query(o << 1 | 1, M+1, R, M+1, qr);
}
maintain(o, L, R);
}
}

void build(int o, int L, int R)
{
if(L == R) maxv[o] = minv[o] = sum[o] = a[L];
else
{
int M = (L + R) >> 1;
build(o << 1, L, M);
build(o << 1 | 1, M+1, R);
maintain(o, L, R);
}
}

int main()
{
freopen("input.txt","r",stdin);
freopen("out2.txt","w",stdout);

int n, q;
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, 1, n);
while(q--)
{
int ql, qr;
scanf("%d", &op);
if(op <= 2)
{
scanf("%d%d%d", &ql, &qr, &qv);
update(1, 1, n, ql, qr);
}
else
{
scanf("%d%d", &ql, &qr);
_sum = _max = 0; _min = INF;
query(1, 1, n, ql, qr);
printf("%d %d %d\n", _min, _max, _sum);
}
}

fclose(stdin);
fclose(stdout);
return 0;
}

#### 线段树ppt的好东东

2009年07月23日 140KB 下载

#### 线段树 树状数组 数据结构

2011年07月24日 1.29MB 下载

#### 线段树区间更新代码

2017年12月22日 2KB 下载

#### 国家队论文——线段树

2009年06月06日 170KB 下载

#### 帮助理解的线段树

2013年07月29日 166KB 下载

#### 线段树入门

2018年03月29日 1.67MB 下载

#### 线段树 与 信息学竞赛 pdf 非常有用 acm

2009年04月28日 196KB 下载

#### 线段树PPT两个，所有常规用法

2009年09月28日 97KB 下载

#### 线段树及其应用pptppt

2011年01月29日 172KB 下载