您的位置:首页 > 其它

uva 11992 线段树

2015-10-01 16:59 218 查看
因为行数比较少(最多20),所以可以考虑每行建立一颗线段树进行操作,进而想到可以只建一颗线段树,将矩阵查询变成多次线段查询。另外需要注意的是两种lazy标记的优先级,只要有赋值操作,之前的所有操作都会被替代,所以pushdown的时候要先放下赋值的lazy标记。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int INF = 1000000007;
const int N = 1000001;

struct Node
{
int l, r, maxn, minn, sum, add, v;
} node[N << 2];

void build( int i, int l, int r )
{
node[i].l = l, node[i].r = r;
node[i].sum = node[i].maxn = node[i].minn = node[i].add = 0;
node[i].v = -1;
if ( l == r ) return ;
int mid = ( l + r ) >> 1;
build( i << 1, l, mid );
build( i << 1 | 1, mid + 1, r );
}

void pushup( int i )
{
node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn );
node[i].minn = min( node[i << 1].minn, node[i << 1 | 1].minn );
}

void pushdown( int i )
{
int lc = i << 1, rc = lc | 1;
if ( node[i].v != -1 )
{
node[lc].v = node[lc].maxn = node[lc].minn = node[i].v;
node[lc].sum = ( node[lc].r - node[lc].l + 1 ) * node[i].v;
node[lc].add = 0;
node[rc].v = node[rc].maxn = node[rc].minn = node[i].v;
node[rc].sum = ( node[rc].r - node[rc].l + 1 ) * node[i].v;
node[rc].add = 0;
node[i].v = -1;
}
if ( node[i].add )
{
node[lc].add += node[i].add;
node[lc].sum += ( node[lc].r - node[lc].l + 1 ) * node[i].add;
node[rc].add += node[i].add;
node[rc].sum += ( node[rc].r - node[rc].l + 1 ) * node[i].add;
node[lc].maxn += node[i].add;
node[lc].minn += node[i].add;
node[rc].maxn += node[i].add;
node[rc].minn += node[i].add;
node[i].add = 0;
}
}

void update( int i, int l, int r, int add )
{
if ( node[i].l == l && node[i].r == r )
{
node[i].maxn += add;
node[i].minn += add;
node[i].sum += ( node[i].r - node[i].l + 1 ) * add;
node[i].add += add;
return ;
}
pushdown(i);
int mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
update( i << 1, l, r, add );
}
else if ( l > mid )
{
update( i << 1 | 1, l, r, add );
}
else
{
update( i << 1, l, mid, add );
update( i << 1 | 1, mid + 1, r, add );
}
pushup(i);
}

void modify( int i, int l, int r, int v )
{
if ( node[i].l == l && node[i].r == r )
{
node[i].maxn = v;
node[i].minn = v;
node[i].sum = ( node[i].r - node[i].l + 1 ) * v;
node[i].v = v;
node[i].add = 0;
return ;
}
pushdown(i);
int mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
modify( i << 1, l, r, v );
}
else if ( l > mid )
{
modify( i << 1 | 1, l, r, v );
}
else
{
modify( i << 1, l, mid, v );
modify( i << 1 | 1, mid + 1, r, v );
}
pushup(i);
}

Node query( int i, int l, int r )
{
if ( node[i].l == l && node[i].r == r )
{
return node[i];
}
pushdown(i);
int mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
return query( i << 1, l, r );
}
else if ( l > mid )
{
return query( i << 1 | 1, l, r );
}
else
{
Node nl = query( i << 1, l, mid );
Node nr = query( i << 1 | 1, mid + 1, r );
Node res;
res.maxn = max( nl.maxn, nr.maxn );
res.minn = min( nl.minn, nr.minn );
res.sum = nl.sum + nr.sum;
return res;
}
}

int main ()
{
int row, col, m;
while ( scanf("%d%d%d", &row, &col, &m) != EOF )
{
build( 1, 1, row * col );
while ( m-- )
{
int op, x1, y1, x2, y2, num;
scanf("%d", &op);
if ( op == 1 )
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &num);
for ( int j = x1; j <= x2; j++ )
{
update( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2, num );
}
}
else if ( op == 2 )
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &num);
for ( int j = x1; j <= x2; j++ )
{
modify( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2, num );
}
}
else
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int s = 0, ma = -INF, mi = INF;
for ( int j = x1; j <= x2; j++ )
{
Node tmp = query( 1, ( j - 1 ) * col + y1, ( j - 1 ) * col + y2 );
s += tmp.sum;
ma = max( ma, tmp.maxn );
mi = min( mi, tmp.minn );
}
printf("%d %d %d\n", s, mi, ma);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: