主体段树,要注意,因为有set和add操作,当慵懒的标志下推。递归优先set,后复发add,每次运行set行动add马克清0

WA了好几次是由于计算那一段的时候出问题了,可笑的是我对着模板找了一个多小时的错。

#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
#define lson pos << 1
#define rson pos << 1|1
typedef unsigned long long ULL;
typedef long long LL;
const int maxn = 1111111;
const int INF = 1 << 30;
struct Node{
int left,right;
int max_value,min_value,sum_value;
int col;
int col2;
}tr[maxn << 2];
struct Ans{
int min_value;
int max_value;
int sum_value;
Ans(int a = INF,int b = 0,int c = 0):min_value(a),max_value(b),sum_value(c){};
};
int n,m,k;
void pushdown(int pos){
if(tr[pos].col){
int len1 = tr[lson].right - tr[lson].left + 1;
int len2 = tr[rson].right - tr[rson].left + 1;
tr[lson].sum_value += (tr[pos].col * len1);
tr[lson].max_value += tr[pos].col;
tr[lson].min_value += tr[pos].col;
tr[rson].sum_value += (tr[pos].col * len2);
tr[rson].max_value += tr[pos].col;
tr[rson].min_value += tr[pos].col;
tr[lson].col += tr[pos].col;
tr[rson].col += tr[pos].col;
tr[pos].col = 0;
}
return ;
}
void pushdown2(int pos){
if(tr[pos].col2 >= 0){
int len1 = tr[lson].right - tr[lson].left + 1;
int len2 = tr[rson].right - tr[rson].left + 1;
tr[lson].sum_value = (tr[pos].col2 * len1);
tr[lson].max_value = tr[pos].col2;
tr[lson].min_value = tr[pos].col2;
tr[rson].sum_value = (tr[pos].col2 * len2);
tr[rson].max_value = tr[pos].col2;
tr[rson].min_value = tr[pos].col2;
tr[lson].col2 = tr[pos].col2; tr[lson].col = 0; //set递推须要清空求和
tr[rson].col2 = tr[pos].col2; tr[rson].col = 0;
tr[pos].col2 = -1;
}
return ;
}
void pushup(int pos){
tr[pos].sum_value = tr[lson].sum_value + tr[rson].sum_value;
tr[pos].max_value = max(tr[lson].max_value,tr[rson].max_value);
tr[pos].min_value = min(tr[lson].min_value,tr[rson].min_value);
return ;
}
void BuildTree(int L,int R,int pos){
tr[pos].left = L; tr[pos].right = R; tr[pos].col = 0;tr[pos].col2 = -1;
tr[pos].max_value = 0; tr[pos].min_value = 0; tr[pos].sum_value = 0;
if(L == R) return ;
int m = (L + R) >> 1;
BuildTree(L,m,lson);
BuildTree(m + 1,R,rson);
return ;
}
void TreeAdd(int l,int r,int add,int pos){
if(l <= tr[pos].left && tr[pos].right <= r){
int len = tr[pos].right - tr[pos].left + 1;
tr[pos].max_value += add; tr[pos].min_value += add;
tr[pos].sum_value += (add * len); tr[pos].col += add;
return ;
}
pushdown2(pos);
pushdown(pos);
int m = (tr[pos].left + tr[pos].right) >> 1;
if(l <= m)
TreeAdd(l,r,add,lson);
if(r > m)
TreeAdd(l,r,add,rson);
pushup(pos);
}
void TreeSet(int l,int r,int value,int pos){
if(l <= tr[pos].left && tr[pos].right <= r){
int len = tr[pos].right - tr[pos].left + 1;
tr[pos].max_value = value; tr[pos].min_value = value;
tr[pos].sum_value = (value * len); tr[pos].col2 = value;tr[pos].col = 0;
return ;
}
pushdown2(pos);
pushdown(pos);
int m = (tr[pos].left + tr[pos].right) >> 1;
if(l <= m)
TreeSet(l,r,value,lson);
if(r > m)
TreeSet(l,r,value,rson);
pushup(pos);
}
Ans Query(int l,int r,int pos){
if(l <= tr[pos].left && tr[pos].right <= r){
return Ans(tr[pos].min_value,tr[pos].max_value,tr[pos].sum_value);
}
pushdown2(pos);
pushdown(pos);
int m = (tr[pos].left + tr[pos].right) >> 1;
Ans a,b;
if(l <= m)
a = Query(l,r,lson);
if(r > m)
b = Query(l,r,rson);
pushup(pos);
return Ans(min(a.min_value,b.min_value),max(a.max_value,b.max_value),a.sum_value + b.sum_value);
}
int main(){
while(scanf("%d%d%d",&n,&m,&k) != EOF){
BuildTree(1,n * m,1);
while(k--){
int t;
scanf("%d",&t);
if(t == 1){
int x1,y1,x2,y2,v;//add
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v);
for(int i = x1 ; i <= x2 ; i++){
int l = (i - 1) * m + y1;
int r = (i - 1) * m + y2;
TreeAdd(l,r,v,1);
}
}
else if(t == 2){
int x1,y1,x2,y2,v;//add
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v);
for(int i = x1 ; i <= x2 ; i++){
int l = (i - 1) * m + y1;
int r = (i - 1) * m + y2;
TreeSet(l,r,v,1);
}
}
else if(t == 3){
int x1,y1,x2,y2;
Ans t;
int MAX = 0,MIN = INF,SUM = 0;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
for(int i = x1 ; i <= x2 ; i++){
int l = (i - 1) * m + y1;
int r = (i - 1) * m + y2;
t = Query(l,r,1);
SUM += t.sum_value;
MAX = max(MAX,t.max_value);MIN = min(MIN,t.min_value);
}
printf("%d %d %d\n",SUM,MIN,MAX);
}
}
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

【UVA】11992 - Fast Matrix Operations(段树模板)的更多相关文章

  1. UVA 11992 - Fast Matrix Operations(段树)

    UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中加入值a,设置值a.查询和 思路:因为最多20列,所以全然能够当作20个线段树 ...

  2. uva 11992 Fast Matrix Operations 线段树模板

    注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...

  3. UVA11992 - Fast Matrix Operations(段树部分的变化)

    UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v ...

  4. 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

    题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...

  5. UVA 11992 Fast Matrix Operations(线段树:区间修改)

    题目链接 2015-10-30 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=s ...

  6. UVA 11992 Fast Matrix Operations (二维线段树)

    解法:因为至多20行,所以至多建20棵线段树,每行建一个.具体实现如下,有些复杂,慢慢看吧. #include <iostream> #include <cstdio> #in ...

  7. UVa 11992 Fast Matrix Operations (线段树,区间修改)

    题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...

  8. uva 11992 - Fast Matrix Operations

    简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...

  9. UVA 11992 Fast Matrix Operations (降维)

    题意:对一个矩阵进行子矩阵操作. 元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作. 一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测 ...

随机推荐

  1. [Angular] Separating Structural Styles From Theme Styles - Making Components Themeable

    For the component's css file, we can improt two css files: common.css default-theme.css @import &quo ...

  2. js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)

    js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...

  3. xmpp即时通讯协议的特性---长处和缺点!

    xmpp协议的定义? XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性. 因此.基于XMPP的应用具有超强的可扩展性.经过扩展以后的XMPP能够通过发送扩展的信 ...

  4. ebook https://salttiger.com/category/notification/

    https://salttiger.com/category/notification/ 因为个人精力有限,持续搜集.整理.分享电子书已经占用我大部分业余时间,今后不再给评论区留言的朋友们找书,还希望 ...

  5. CSDN编程挑战——《交替字符串》

    交替字符串 题目详情: 假设字符串str3可以由str1和str2中的字符按顺序交替形成,那么称str3为str1和str2的交替字符串.比如str1="abc",str2=&qu ...

  6. php标准库中QplQueue队列如何使用?

    php标准库中QplQueue队列如何使用? 一.总结 1.new对象,然后通过enqueue方法和dequeue方法使用. 二.php标准库中QplQueue队列如何使用? 队列这种数据结构更简单, ...

  7. Mysql存储过程中使用cursor

    一.表 学生表 CREATE TABLE `t_student` (    `stuNum` int(11) NOT NULL auto_increment,    `stuName` varchar ...

  8. BZOJ3073 Journeys - 线段树优化建边

    传送门 题意: Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路: ...

  9. 使用apidoc 生成Restful web Api文档

    在项目开发过程中,总会牵扯到接口文档的设计与编写,之前使用的都是office工具,写一个文档,总也是不够漂亮和直观.好在git上的开源大神提供了生成文档的工具,so来介绍一下! 该工具是Nodejs的 ...

  10. Android中获取当前位置的使用步骤

    在Android中得到当前位置的步骤 1.在AndroidManifest.xml中声明权限 android.permission.ACCESS_FINE_LOCATION(或者android.per ...