UVA 11992 ——线段树(区间修改)
解题思路:
将矩阵每一行建立一棵线段树,进而变成一维问题求解。注意数组要开 4*N
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int maxn = + ; const int INF = ;
int q, x1_, x2_, y1, y2, v_add, v_set; struct segment_tree {
int sumv[4*maxn],minv[4*maxn],maxv[4*maxn];
int addv[4*maxn], setv[4*maxn];
void maintain(int o, int L, int R) {
int lc = *o, rc = *o + ;
sumv[o] = minv[o] = maxv[o] = ;
if(setv[o] >= ) {
sumv[o] = setv[o] * (R-L+);
minv[o] = maxv[o] = setv[o];
}
else if(R > L) {
sumv[o] = sumv[lc] + sumv[rc];
minv[o] = min(minv[lc], minv[rc]);
maxv[o] = max(maxv[lc], maxv[rc]);
}
minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+);
}
void pushdown(int o) {
int lc = *o, rc = *o+;
if(setv[o] >= ) {
setv[lc] = setv[rc] = setv[o];
addv[lc] = addv[rc] = ;
setv[o] = -;
}
if(addv[o] > ) {
addv[lc] += addv[o];
addv[rc] += addv[o];
addv[o] = ;
}
}
void update_add(int o, int L, int R) {
int lc = *o, rc = o*+;
if(y1 <= L && y2 >= R) {
addv[o] += v_add;
}
else {
pushdown(o);
int M = L + (R-L)/;
if(y1 <= M) update_add(lc, L, M); else maintain(lc, L, M);
if(y2 > M) update_add(rc, M+, R);else maintain(rc, M+, R);
}
maintain(o, L, R);
}
void update_set(int o, int L, int R) {
int lc = *o, rc = o*+;
if(y1 <= L && y2 >= R) {
setv[o] = v_set;
addv[o] = ;
}
else {
pushdown(o);
int M = L + (R-L)/;
if(y1 <= M) update_set(lc, L, M); else maintain(lc, L, M);
if(y2 > M) update_set(rc, M+, R); else maintain(rc, M+, R);
}
maintain(o, L, R);
} void query(int o, int L, int R, int add, int& _min, int& _max, int& _sum) {
if(setv[o] >= ) {
_sum += (add+setv[o]+addv[o]) * (min(R, y2)-max(L, y1)+);
_min = min(_min, setv[o]+addv[o]+add);
_max = max(_max, setv[o]+addv[o]+add);
}
else if(y1 <= L && y2 >= R) {
_sum += sumv[o] + add * (R-L+);
_min = min(_min, minv[o]+add);
_max = max(_max, maxv[o]+add);
}
else {
int M = L + (R-L)/;
if(y1 <= M) query(o*, L, M, add+addv[o], _min, _max, _sum);
if(y2 > M) query(o*+, M+, R, add+addv[o], _min, _max, _sum);
}
} void init() {
memset(setv, -, sizeof setv);
memset(addv, , sizeof addv);
memset(sumv, , sizeof sumv);
memset(minv, , sizeof minv);
memset(maxv, , sizeof maxv);
}
};
int r, c, m;
const int maxr = + ; segment_tree tree[maxr]; int main(int argc, const char * argv[]) { while(scanf("%d%d%d", &r, &c, &m) == ){ for(int i = ; i < maxr; i++) tree[i].init();
for(int i = ; i < m; i++) { scanf("%d%d%d%d%d", &q, &x1_, &y1, &x2_, &y2);
if(q == ){
scanf("%d", &v_add);
for(int x = x1_; x <= x2_; x++) {
tree[x].update_add(, , c);
}
}
if(q == ) {
scanf("%d", &v_set);
for(int x = x1_; x <= x2_; x++) {
tree[x].update_set(, , c);
}
}
if(q == ){
int gmin = INF, gmax = -INF, gsum = ;
for(int x = x1_; x <= x2_; x++) {
int _min = INF, _max = -INF, _sum = ;
tree[x].query(, , c, ,_min, _max, _sum);
gsum += _sum;
gmin = min(gmin, _min);
gmax = max(gmax, _max);
}
printf("%d %d %d\n", gsum, gmin, gmax);
}
}
}
return ;
}
UVA 11992 ——线段树(区间修改)的更多相关文章
- UVa 11992 (线段树 区间修改) Fast Matrix Operations
比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...
- Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)
题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- E - Just a Hook HDU - 1698 线段树区间修改区间和模版题
题意 给出一段初始化全为1的区间 后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...
- HDU 4027 Can you answer these queries? (线段树区间修改查询)
描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...
- poj2528 Mayor's posters(线段树区间修改+特殊离散化)
Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...
- hiho_1078_线段树区间修改
题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...
- HDU - 1698 线段树区间修改,区间查询
这就是很简单的基本的线段树的基本操作,区间修改,区间查询,对区间内部信息打上laze标记,然后维护即可. 我自己做的时候太傻逼了...把区间修改写错了,对给定区间进行修改的时候,mid取的是节点的左右 ...
随机推荐
- Hdu 4497
题目链接 已知 gcd(x, y, z) = G, lcm(x, y, z) = L, 求有多少种组合(x, y, z)可以满足条件.G, L都在32位int范围内. 思路: 素数分解 + 容斥 L ...
- Convert Sorted Array to Binary Search Tree转换成平衡二查搜索树
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 二分 ...
- FinalShell for Mac
Mac一键安装脚本 curl -o finalshell_install.sh www.hostbuf.com/downloads/finalshell_install.sh;chmod +x fin ...
- 【NS2】WiMAX_NS2说明文档(转载)
关于目前NS2中WiMAX模块的说明 (1)美国NIST(National Institute of Standards and Technology)版, 可以从NIST主页获得,2007.04 r ...
- Visual Studio中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法
解决方案:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设置为False,问题轻松解决. 问题分析: 1.”嵌入互操作类型”中的嵌入就是引进.导入的意思,类似于c#中using,c中 ...
- 2019-1-16-win10-uwp-发布的时候-ILC-编译不通过
title author date CreateTime categories win10 uwp 发布的时候 ILC 编译不通过 lindexi 2019-1-16 20:37:5 +0800 20 ...
- jquery attr()和prop()方法的区别
$('').attr()返回的是html对象 $('').prop()返回的是DOM对象 attr(): attr() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值,则返回第一个匹配元素 ...
- 设计模式 - 工厂模式(factory pattern) 具体解释
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/27081511 工厂模式(factory pa ...
- 从开源小白到 Apache Member,我的成长之路
我们走过的每一步路,都会留下印记,越坚实,越清晰. 近日,Apache 软件基金会(ASF)官方 Blog 宣布全球新增 40 位 Apache Member,张乎兴有幸成为其中一位. 目前,全球共有 ...
- Android 申请权限示例
1.在Mainifest.xml中添加 <?xml version="1.0" encoding="utf-8"?> <manifest xm ...