【UVA】11992 - Fast Matrix Operations(段树模板)

主体段树,要注意,因为有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;
}

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

时间: 2024-10-15 20:28:09

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

UVA 11992(Fast Matrix Operations-线段树区间加&amp;改)[Template:SegmentTree]

Fast Matrix Operations There is a matrix containing at most 106 elements divided into r rows and c columns. Each element has a location (x,y) where 1<=x<=r,1<=y<=c. Initially, all the elements are zero. You need to handle four kinds of operati

UVa 11992 Fast Matrix Operations (线段树)

Fast Matrix Operations Description There is a matrix containing at most 106 elements divided into r rows and c columns. Each element has a location (x, y) where 1 ≤ x ≤ r, 1 ≤ y ≤ c. Initially, all the elements are zero. You need to handle four kinds

UVA 11992 - Fast Matrix Operations

Fast Matrix Operations There is a matrix containing at most 106 elements divided into r rows and c columns. Each element has a location (x,y) where 1<=x<=r,1<=y<=c. Initially, all the elements are zero. You need to handle four kinds of operati

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

UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v 把由x1,y1, x2, y2构成的子矩阵里的每一个元素都加上v. 2 x1, y1, x2, y2, v 把这个子矩阵的每一个元素都改动为v. 3 x1, y1, x2, y2 查询这个子矩阵的元素之和,和这些元素的最大值和最小值. 解题思路:由于矩阵的行最多20行,所以能够将这个矩阵的元素构建一

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

题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using namespace std; #define lson l, mid, o << 1 #define rson mid + 1, r, o << 1 | 1 typedef long long ll; const int INF = 0x3f3f3f3f; const int N =

UVa 11992 Fast Matrix Operations(线段树双懒操作,二维转一维)

题意:给个r*c的矩形,三种操作,将一个子矩形权值+v,将一个子矩阵权值赋值为v,查询一个子矩阵sum,max,min.起初矩阵权值为0,保证r<=20,r*c<=1e6,操作次数不超过10000 链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697 题解:将二维转一维,设当前点为(x,y),则它在线段树上的点为(x-1)*c+y,由于行不超过20行,不妨枚举每一行,去操作.对于一维的线段树,要进行赋值,加法

UVA 11992 Fast Matrix Operations (降维)

题意:对一个矩阵进行子矩阵操作. 元素对多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作. 一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后建树复杂度是min(RlogC,ClogR). 代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间.但是也有缺点,比如推区间结点数量的时候会麻烦一点. #include<bits/stdc++.h> using namespace std; const

UVA11992 - Fast Matrix Operations ( 线段树 + 区间修改 + 好题 )

UVA11992 - Fast Matrix Operations ( 线段树 + 区间修改 + 好题 ) 这是大白书上的例题,一直放着没有去A掉,这是一道线段树区间修改的好题. 线段树中需要维护三个域 ,max, min, sum,也就是区间最大值,最小值,区间和 题目大意: r 行 c 列 的全0矩阵,支持三个操作 1 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素增加v 2 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素设为v 3 x1 y1

【UVA】11992 - Fast Matrix Operations(线段树模板)

基本的线段树,需要注意的是由于有set和add操作,懒惰标记下推的时候,优先递推set,之后递推add,每次执行set操作将add标记清0 WA了好几次是因为计算那一段的时候出问题了,可笑的是我对着模板找了一个多小时的错. #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<algorithm> using na