#define MAXSIZE 100
int sum[MAXSIZE << 2];
//建立线段树 基于完全二叉树
void build(int left,int right,int cur)
{
//是叶子节点
if (left == right)
{
sum[cur] = left;
return;
}
//添加叶子节点
int mid = (left + right) >> 1;
build(left, mid, cur * 2);
build(mid + 1, right, cur * 2 + 1);
//叶子节点添加完成 添加父节点
sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}
//更新区间段
void update(int changeLeft,int changeRight,int updateValue,int curLeft,int curRight,int cur)
{
//终止条件 不在更新区间
if (curLeft > changeRight || curRight < changeLeft)
return;
//当前区间 在 更新区间内 不能这么做 因为子树没有更新 如果查询子树就gg了
/*if (curLeft >= changeLeft && curRight <= changeRight)
{
sum[cur] = (curRight - curLeft + 1) * updateValue;
return;
}*/
if (curLeft == curRight)
{
sum[cur] = updateValue;
return;
}
int mid = (curLeft + curRight) >> 1;
//检查左子树是否需要更新
if (mid >= changeLeft)
{
update(changeLeft, changeRight, updateValue, curLeft, mid, cur * 2);
}
//检查右子树是否需要更新
if (mid < changeRight)
{
update(changeLeft, changeRight, updateValue, mid + 1, curRight, cur * 2+1);
}
//更新当前节点
sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}
int query(int qLeft, int qRight, int curLeft, int curRight, int cur)
{
//不在区间内
if (curRight < qLeft || curLeft > qRight)
return 0;
//当前区间 在查询区间内
if (curLeft >= qLeft && curRight <= qRight)
{
return sum[cur];
}
int result = 0;
int mid = (curLeft + curRight) >> 1;
//是否在左区间
if (mid >= qLeft)
{
result+=query(qLeft, qRight, curLeft, mid, cur * 2);
}
//是否在右区间
if (mid < qRight)
{
result+=query(qLeft, qRight, mid + 1, curRight, cur * 2 + 1);
}
return result;
}
int main()
{
memset(sum, 0, sizeof(sum));
memset(lazy, 0, sizeof(lazy));
build(1, 10, 1);
cout << query(3, 6, 1, 10, 1) <
//加入lazy标记
void push_down(int cur,int len)
{
if (lazy[cur] == 0) return;
lazy[cur * 2] = lazy[cur];
lazy[cur * 2+1] = lazy[cur];
sum[cur * 2] = lazy[cur * 2] * (len - len / 2);
sum[cur * 2 + 1] = lazy[cur * 2 + 1] * (len / 2);
lazy[cur] = 0;
}
//更新区间段
void update(int changeLeft,int changeRight,int updateValue,int curLeft,int curRight,int cur)
{
//终止条件 不在更新区间
if (curLeft > changeRight || curRight < changeLeft)
return;
//当前区间 在 更新区间内 不能这么做 因为子树没有更新 如果查询子树就gg了
//给子树一个标志 下次查到子树的时候就更新
if (curLeft >= changeLeft && curRight <= changeRight)
{
sum[cur] = (curRight - curLeft + 1) * updateValue;
lazy[cur] = updateValue;
return;
}
push_down(cur, curRight - curLeft + 1);
//到叶子节点终止
/*if (curLeft == curRight)
{
sum[cur] = updateValue;
return;
}*/
int mid = (curLeft + curRight) >> 1;
//检查左子树是否需要更新
if (mid >= changeLeft)
{
update(changeLeft, changeRight, updateValue, curLeft, mid, cur * 2);
}
//检查右子树是否需要更新
if (mid < changeRight)
{
update(changeLeft, changeRight, updateValue, mid + 1, curRight, cur * 2+1);
}
//更新当前节点
sum[cur] = sum[cur * 2] + sum[cur * 2 + 1];
}
int query(int qLeft, int qRight, int curLeft, int curRight, int cur)
{
//不在区间内
if (curRight < qLeft || curLeft > qRight)
return 0;
//当前区间 在查询区间内
if (curLeft >= qLeft && curRight <= qRight)
{
return sum[cur];
}
push_down(cur, curRight - curLeft + 1);
int result = 0;
int mid = (curLeft + curRight) >> 1;
//是否在左区间
if (mid >= qLeft)
{
result+=query(qLeft, qRight, curLeft, mid, cur * 2);
}
//是否在右区间
if (mid < qRight)
{
result+=query(qLeft, qRight, mid + 1, curRight, cur * 2 + 1);
}
return result;
}