UVA - 11992:Fast Matrix Operations

线段树,注意tag优先级

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 1000005
using namespace std;
struct Node{
    int sumv,maxv,minv,tag_add,tag_change;
    Node(int p1=0,int p2=0,int p3=0,int p4=0,int p5=0){
        sumv=p1,maxv=p3,minv=p2,tag_add=p4,tag_change=p5;
    }
}dat[22][MAXN<<2];
int a[22][MAXN];
Node Merge(Node t1,Node t2){
    if(t1.tag_add==-1)return t2;
    if(t2.tag_add==-1)return t1;
    Node ret;
    ret.sumv=t1.sumv+t2.sumv;
    ret.maxv=max(t1.maxv,t2.maxv);
    ret.minv=min(t1.minv,t2.minv);
    return ret;
}
void build(Node d[],int x,int k,int L,int R){
    if(L+1==R){
        d[k].sumv=d[k].maxv=d[k].minv=a[x][L];
        return;
    }
    build(d,x,k<<1,L,(L+R)>>1);
    build(d,x,k<<1|1,(L+R)>>1,R);
    d[k]=Merge(d[k<<1],d[k<<1|1]);
}
void pushdown(Node d[],int k,int L,int R){
    int lc=(k<<1),rc=(k<<1|1);
    if(d[k].tag_change){
        d[lc].tag_add=0;
        d[lc].tag_change=d[k].tag_change;
        d[lc].sumv=d[k].tag_change*(((L+R)>>1)-L);
        d[lc].maxv=d[k].tag_change;
        d[lc].minv=d[k].tag_change;
        d[rc].tag_add=0;
        d[rc].tag_change=d[k].tag_change;
        d[rc].sumv=d[k].tag_change*(R-((L+R)>>1));
        d[rc].maxv=d[k].tag_change;
        d[rc].minv=d[k].tag_change;
        d[k].tag_change=0;
    }
    if(d[k].tag_add){
        d[lc].tag_add+=d[k].tag_add;
        d[lc].sumv+=d[k].tag_add*(((L+R)>>1)-L);
        d[lc].maxv+=d[k].tag_add;
        d[lc].minv+=d[k].tag_add;
        d[rc].tag_add+=d[k].tag_add;
        d[rc].sumv+=d[k].tag_add*(R-((L+R)>>1));
        d[rc].maxv+=d[k].tag_add;
        d[rc].minv+=d[k].tag_add;
        d[k].tag_add=0;
    }
}
void add(Node d[],int a,int b,int k,int L,int R,int x){
    if(b<=L||R<=a){
        return;
    }
    else if(a<=L&&R<=b){
        d[k].tag_add+=x;
        d[k].sumv+=x*(R-L);
        d[k].maxv+=x;
        d[k].minv+=x;
    }
    else{
        if(d[k].tag_add||d[k].tag_change){
            pushdown(d,k,L,R);
        }
        add(d,a,b,k<<1,L,(L+R)>>1,x);
        add(d,a,b,k<<1|1,(L+R)>>1,R,x);
        d[k]=Merge(d[k<<1],d[k<<1|1]);
    }
}
void change(Node d[],int a,int b,int k,int L,int R,int x){
    if(b<=L||R<=a){
        return;
    }
    else if(a<=L&&R<=b){
        d[k].tag_add=0;
        d[k].tag_change=x;
        d[k].sumv=x*(R-L);
        d[k].maxv=x;
        d[k].minv=x;
    }
    else{
        if(d[k].tag_add||d[k].tag_change){
            pushdown(d,k,L,R);
        }
        change(d,a,b,k<<1,L,(L+R)>>1,x);
        change(d,a,b,k<<1|1,(L+R)>>1,R,x);
        d[k]=Merge(d[k<<1],d[k<<1|1]);
    }
}
Node query(Node d[],int a,int b,int k,int L,int R){
    if(b<=L||R<=a){
        return Node(-1,-1,-1,-1,-1);
    }
    else if(a<=L&&R<=b){
        return d[k];
    }
    else{
        if(d[k].tag_add||d[k].tag_change){
            pushdown(d,k,L,R);
        }
        Node lc=query(d,a,b,k<<1,L,(L+R)>>1);
        Node rc=query(d,a,b,k<<1|1,(L+R)>>1,R);
        return Merge(lc,rc);
    }
}
void debug(Node d[],int k,int L,int R){
    if(d[k].tag_add||d[k].tag_change){
        pushdown(d,k,L,R);
    }
    if(L+1==R){
        printf("%d ",d[k]);
        return;
    }
    debug(d,k<<1,L,(L+R)>>1);
    debug(d,k<<1|1,(L+R)>>1,R);
}
int m,n,T;
void solve(){
    for(int i=1;i<=m;i++){
        build(dat[i],i,1,1,n+1);
    }
    while(T--){
        int p;scanf("%d",&p);
        int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(1==p){
            int v;scanf("%d",&v);
            for(int i=x1;i<=x2;i++){
                add(dat[i],y1,y2+1,1,1,n+1,v);
            }
        }
        else if(2==p){
            int v;scanf("%d",&v);
            for(int i=x1;i<=x2;i++){
                change(dat[i],y1,y2+1,1,1,n+1,v);
            }
        }
        else{
            Node ans=query(dat[x1],y1,y2+1,1,1,n+1);
            for(int i=x1+1;i<=x2;i++){
                Node t=query(dat[i],y1,y2+1,1,1,n+1);
                ans.sumv+=t.sumv;
                ans.maxv=max(ans.maxv,t.maxv);
                ans.minv=min(ans.minv,t.minv);
            }
            printf("%d %d %d\n",ans.sumv,ans.minv,ans.maxv);
        }
    }
}
int main()
{
//    freopen("data.in","r",stdin);
//    freopen("my.in","w",stdout);
    while(~scanf("%d%d%d",&m,&n,&T)){
        solve();
    }
}
时间: 2024-10-17 11:11:40

UVA - 11992:Fast Matrix Operations的相关文章

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val: 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val: 3 x1 y1 x2 y2 val 表示输

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

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

Fast Matrix Operations

uva11992:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143 题意:给你n*m的矩阵初始化的时候矩阵里面的元素全部是0,对于这个矩阵有3中操作. 1 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部加上v 2 x1 y1 x2 y2 v   把(x1 y1 x2 y2)子矩阵 里面的元素全部置成

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行,所以能够将这个矩阵的元素构建一

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(线段树双懒操作,二维转一维)

题意:给个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

【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