#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
using namespace std;
typedef long long LL;
const LL LINF = (1LL <<63);
const int INF = 1 << 31;
const int NS = 500010;
const int MS = 19;
const int MOD = 1000000007;
typedef LL Ntype;
const int TSIZE = 500010;
struct tNode{
int ls, rs; //左右儿子的节点ID
int lid, rid, len; //节点的左右边界及长度
Ntype minv, maxv; //记录子树节点的价值最值
Ntype sumv; //记录子树节点的价值和
Ntype addv; //记录子树节点的增量
bool isLeaf()
{
return (lid == rid);
}
};
struct lineTree{
#define lson(x) (x << 1)
#define rson(x) ((x << 1) + 1)
#define pmid(l, r) ((l + r) >> 1)
int maxrt;
tNode wt[TSIZE << 2];
Ntype val[TSIZE];
Ntype cmax(Ntype va, Ntype vb)
{
return (va > vb? va : vb);
}
Ntype cmin(Ntype va, Ntype vb)
{
return (va < vb? va : vb);
}
void PushUpUpdate(int rt)
{
int ls = wt[rt].ls;
int rs = wt[rt].rs;
wt[rt].maxv = cmax(wt[ls].maxv, wt[rs].maxv);
wt[rt].minv = cmin(wt[ls].minv, wt[rs].minv);
wt[rt].sumv = wt[ls].sumv + wt[rs].sumv;
}
void PushDownUpdate(int rt)
{
if(0 != wt[rt].addv)
{
int ls = wt[rt].ls;
int rs = wt[rt].rs;
Ntype addv = wt[rt].addv;
wt[ls].addv += addv;
wt[ls].maxv += addv;
wt[ls].minv += addv;
wt[ls].sumv += wt[ls].len * addv;
wt[rs].addv += addv;
wt[rs].maxv += addv;
wt[rs].minv += addv;
wt[rs].sumv += wt[rs].len * addv;
wt[rt].addv = 0;
}
}
void build(int rt, int l, int r)
{
if(rt > maxrt) maxrt = rt;
// printf("(%d,%d,%d)\n", rt, l, r);
wt[rt].len = r - l + 1;
wt[rt].lid = l;
wt[rt].rid = r;
wt[rt].addv = 0;
if(l == r)
{
wt[rt].ls = -1;
wt[rt].rs = -1;
wt[rt].maxv = wt[rt].minv = val[r];
wt[rt].sumv = wt[rt].maxv;
return ;
}
else
{
wt[rt].ls = lson(rt);
wt[rt].rs = rson(rt);
}
int mid = pmid(wt[rt].lid, wt[rt].rid);
build(lson(rt), l, mid);
build(rson(rt), mid + 1, r);
PushUpUpdate(rt);
}
void update(int rt, int l, int r, int op, Ntype val)
{
if(l <= wt[rt].lid && wt[rt].rid <= r)
{
//如果操作为区间增加val
wt[rt].addv += val;
wt[rt].maxv += val;
wt[rt].minv += val;
wt[rt].sumv += val * wt[rt].len;
return ;
}
if(wt[rt].isLeaf())
{
//正常情况是不会进入此判断的
printf("********正常情况是不会进入此判断的*********\n");
return ;
}
PushDownUpdate(rt);
int mid = pmid(wt[rt].lid, wt[rt].rid);
if(l <= mid)
{
update(lson(rt), l, r, op, val);
}
if(r > mid)
{
update(rson(rt), l, r, op, val);
}
PushUpUpdate(rt);
}
Ntype query(int rt, int l, int r, int op)
{
if(l <= wt[rt].lid && wt[rt].rid <= r)
{
Ntype res;
if(1 == op) //查询最大值
{
res = wt[rt].maxv;
}
else if(2 == op) //查询最小值
{
res = wt[rt].minv;
}
else if(3 == op) //查询区间和
{
res = wt[rt].sumv;
}
return res;
}
PushDownUpdate(rt);
int mid = pmid(wt[rt].lid, wt[rt].rid);
Ntype res;
if(l > mid)
{
res = query(rson(rt), l, r, op);
}
else if(r <= mid)
{
res = query(lson(rt), l, r, op);
}
else
{
if(1 == op) //查询最大值
{
res = cmax(query(lson(rt), l, r, op), query(rson(rt), l, r, op));
}
else if(2 == op) //查询最小值
{
res = cmin(query(lson(rt), l, r, op), query(rson(rt), l, r, op));
}
else if(3 == op) //查询区间和
{
res = query(lson(rt), l, r, op) + query(rson(rt), l, r, op);
}
}
return res;
}
void printNode(int rt)
{
printf("rt = %3d(%3d,%3d) max = %3d min = %3d sum = %3d add = %d\n", rt, wt[rt].lid, wt[rt].rid, wt[rt].maxv, wt[rt].minv, wt[rt].sumv, wt[rt].addv);
}
void printAll()
{
for(int i = 1; i <= maxrt; i++)
{
if(wt[i].lid > 0)
{
printNode(i);
}
}
}
}sTree;
int n, q;
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while(~scanf("%d %d", &n, &q))
{
for(int i = 1; i <= n; i++)
{
scanf("%I64d", &sTree.val[i]);
}
sTree.build(1, 1, n);
int a,b,c;
char ch[10];
for(;q > 0; q--)
{
scanf("%s", ch);
if('C' == ch[0])
{
scanf("%d %d %d", &a, &b, &c);
sTree.update(1, a, b, 1, c);
}
else
{
scanf("%d %d", &a, &b);
printf("%I64d\n", sTree.query(1, a, b, 3));
}
}
}
return 0;
}
线段树模板(poj3468)
最新推荐文章于 2020-05-15 23:49:15 发布