一步一步理解线段树: http://www.cnblogs.com/TenosDoIt/p/3453089.html#f
还是这个地址,这次用到了优化所用的区间延迟更新,时间复杂度是O(lgn)
PS:领教到了不好好命名变量的坑爹之处。。。。。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#define lson root * 2
#define rson root * 2 + 1
using namespace std;
const int X = 100002 << 2;
int Tree[ X ];
int flag[ X ]; //延迟标记
void build ( int root, int ST, int END ) {
if ( ST == END ) {
Tree[ root ] = 1;
flag[ root ] = 0;
} else {
int mid = ( ST + END ) / 2;
build ( lson, ST, mid );
build ( rson, mid + 1, END );
Tree[ root ] = Tree[ lson ] + Tree[ rson ];
}
}
// 延迟更新 时间O(lgn)
// 当前root的标记向下更新
void pushDown ( int root, int st, int end ) {
if ( flag[ root ] ) {
flag[ lson ] = flag[ rson ] = flag[ root ]; //传递z(要修改成)的值给子节点
int mid = ( st + end ) / 2;
Tree[ lson ] =
( mid - st + 1 ) * flag[ root ]; //根代表的和 直接等于这段区间大小 * z
Tree[ rson ] = ( end - ( mid + 1 ) + 1 ) * flag[ root ];
flag[ root ] = 0;
}
}
// ST END --> required
// st,end --> now
void update ( int root, int st, int end, int ST, int END, int val ) {
if ( st > END || end < ST )
return;
//找到要更新的整段区间
if ( st >= ST && end <= END ) {
flag[ root ] = val;
Tree[ root ] = val * ( end - st + 1 ); //更新这一段的根节点总和
return;
}
//建立flag,延迟更新子节点
pushDown ( root, st, end );
int mid = ( st + end ) / 2;
if ( mid >= ST )
update ( lson, st, mid, ST, END, val );
if ( mid < END )
update ( rson, mid + 1, end, ST, END, val );
Tree[ root ] = Tree[ lson ] + Tree[ rson ];
}
int main () {
int n;
scanf ( "%d", &n );
for ( int i = 1; i <= n; ++i ) {
memset ( flag, 0, sizeof ( flag ) );
int N, Q;
scanf ( "%d%d", &N, &Q );
build ( 1, 1, N );
while ( Q-- ) {
int x, y, z;
scanf ( "%d%d%d", &x, &y, &z );
update ( 1, 1, N, x, y, z );
}
printf ( "Case %d: The total value of the hook is %d.\n", i, Tree[ 1 ] );
}
return 0;
}
本文介绍了一种使用线段树进行区间更新的方法,并通过区间延迟更新来优化时间复杂度至O(lgn)。文章提供了详细的代码实现,展示了如何在不完全二叉树结构中维护节点状态和进行区间更新。
808

被折叠的 条评论
为什么被折叠?



