const int maxn = 500005 * 4; //线段树范围要开4倍
struct Tree
{
int l, r, sum, maxx;
};
Tree node[maxn]; //node[maxn]为线段树处理数组
int a[maxn]; //a[maxn]为原数组
void PushUp(int i)
{
node[i].sum = node[i << 1].sum + node[(i << 1) | 1].sum; //线段树求和
node[i].maxx = max(node[i << 1].maxx, node[(i << 1) | 1].maxx); // 线段树求最大值
}
//创建一个tree
void build(int i, int l, int r)
{
node[i].l = l; node[i].r = r;
if (l == r)
{
node[i].maxx = a[l];
node[i].sum = a[l];
return;
}
int mid = (l + r) >> 1;
build(i << 1, l, mid);// 建立mid左边的树 i<<1所表示的是 tree 上的所在点
build((i << 1) | 1, mid + 1, r); //建立mid右边的树采用递推
PushUp(i);
}
int getsum(int i, int l, int r)
{
if (node[i].l == l&&node[i].r == r)
return node[i].sum;
int mid = (node[i].l + node[i].r) >> 1;
if (r <= mid)
{
return getsum(i << 1, l, r);
}
else if (l > mid) {
return getsum((i << 1) | 1, l, r);
}
else
{
return getsum(i << 1, l, mid) + getsum((i << 1) | 1, mid + 1, r);
}
}
int getmax(int i, int l, int r)
{
if (node[i].l == l&&node[i].r == r)
return node[i].maxx;
int mid = (node[i].l + node[i].r) >> 1;
if (r <= mid)
{
return getmax(i << 1, l, r);
}
else if (l>mid)
{
return getmax((i << 1) | 1, l, r);
}
else
{
return max(getmax(i << 1, l, mid), getmax((i << 1) | 1, mid + 1, r));
}
}
void add(int i, int k, int v) //当前更新的节点的编号为i(一般是1为初始编号,具体得看建立树时使用的第一个编号是什么)。
{ //k为需要更新的点的位置,v为修改的值的大小
if (node[i].l == k&&node[i].r == k) //左右端点均和k相等,说明找到了k所在的叶子节点
{
node[i].sum += v;
node[i].maxx += v;
return; //找到了叶子节点就不需要在向下寻找了
}
int mid = (node[i].l + node[i].r) / 2;
if (k <= mid) a
{
add(i << 1, k, v);
}
else
{
add((i << 1) | 1, k, v);
}
PushUp(i);
}
区间的update
const int N = 100005;
LL a[N]; //a[N]储存原数组
LL lazy[N << 2]; //lazy用来记录该节点的每个数值应该加多少
int n, q;
struct Tree
{
int l, r;
LL sum;
int mid()
{
return (l + r) >> 1;
}
}tree[N<<2];
void PushUp(int rt)
{
tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}
void PushDown(int rt,int m)
{
if (lazy[rt])
{
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
tree[rt << 1].sum += lazy[rt] * (m - (m >> 1));
tree[rt << 1 | 1].sum += lazy[rt] * (m >> 1);
lazy[rt] = 0;
}
}
void build(int l, int r, int rt)
{
tree[rt].l = l;
tree[rt].r = r;
lazy[rt] = 0;
if (l == r)
{
tree[rt].sum = a[l];
return;
}
int m = tree[rt].mid();
build(l, m, (rt << 1));
build(m + 1, r, (rt << 1 | 1));
PushUp(rt);
}
void update(LL c, int l, int r, int rt)
{
if (tree[rt].l == l&&tree[rt].r==r)
{
lazy[rt] += c;
tree[rt].sum += c*(r - l + 1);
return;
}
if (tree[rt].l == tree[rt].r)return;
int m = tree[rt].mid();
PushDown(rt, tree[rt].r - tree[rt].l + 1);
if (r <= m)update(c, l, r, rt << 1);
else if (l > m)update(c, l, r, rt << 1 | 1);
else
{
update(c, l, m, rt << 1);
update(c, m + 1, r, rt << 1 | 1);
}
PushUp(rt);
}
LL Query(int l, int r, int rt)
{
if (l == tree[rt].l&&r == tree[rt].r)
{
return tree[rt].sum;
}
int m = tree[rt].mid();
PushDown(rt, tree[rt].r - tree[rt].l + 1);
LL res = 0;
if (r <= m)res += Query(l, r, rt << 1);
else if (l > m)res += Query(l, r, rt << 1 | 1);
else
{
res += Query(l, m, rt << 1);
res += Query(m + 1, r, rt << 1 | 1);
}
return res;
}