• 题目链接:

    https://www.luogu.org/problemnew/show/UVA11992

  • 题目大意:

    一个r*c的矩阵,一开始元素都是0,然后给你m次三种操作,分别是将一个子矩阵中所有元素加上v,将一个子矩阵元素全部修改成v,询问一个子矩阵中所有元素和,最大值和最小值.

  • 思路:

    应该说是一道有点毒瘤的数据结构题(然而时限居然给了5s)了,虽然它的主体只是线段树。我们可以把每一行都看作一棵线段树,这样操作就十分方便了。

    然后就是修改值的操作,对于初学者可能有点棘手,但实际上并不难,我们同样可以用lazy_tag打标记。但是就有一些要注意的东西了,当我们打add(元素加值)标记时是不会影响set(修改值)标记的,但是我们在打set标记时无论你前面add标记是多少,此时就相当于作废,所以直接将add标记赋为0就好了,然后直接修改sum,mi和mx(分别记录该区间的和,最小值,最大值)。

    同时我们可以让query询问函数直接返回一个存了sum,mi,mx的结构体,这样就不用查三次了.

    同时还有一个去要注意的地方,正如我们前面分析的那样,每一行开一颗线段树,但是实际上你真的不能搞一个tree[maxn],然后每一个tree中存一个线段树的结构体,这样是绝壁会爆的(我一开始就这么搞),而是和平常一样搞一个存全部元素的数组,具体怎么做还请看代码,我自认为还是写的比较直观。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
using namespace std;
const int maxn=1000005;
const int inf=0xfffffff;
int r,c,m,v;
int L,R;
struct Tmp{Tmp() : sum(0), mx(-inf),mi(inf) {}//构造函数,非常方便,强烈推荐Tmp(int x,int y,int z) :sum(x),mx(y),mi(z) {}int sum;int mx,mi;
};//query询问时直接返回这个结构体就好了
int sum[maxn<<2],add[maxn<<2],set[maxn<<2],mx[maxn<<2],mi[maxn<<2];
inline void up(int now){sum[now]=sum[now<<1]+sum[now<<1|1];mx[now]=max(mx[now<<1],mx[now<<1|1]);mi[now]=min(mi[now<<1],mi[now<<1|1]);return ;
}
void build(int now,int l,int r){//其实build一点用也没有,请大家忽略if(l==r){mx[now]=0;//-inf;mi[now]=0;//inf;return ;}int mid=(l+r)>>1;build(now<<1,l,mid);build(now<<1|1,mid+1,r);up(now);return ;
}
inline void down(int now,int ln,int rn){//注意看这个push_down函数if(set[now]){//修改标记sum[now<<1]=set[now]*ln;sum[now<<1|1]=set[now]*rn;set[now<<1]=set[now];set[now<<1|1]=set[now];add[now<<1]=add[now<<1|1]=0;mx[now<<1]=mx[now<<1|1]=set[now];mi[now<<1]=mi[now<<1|1]=set[now];set[now]=0;}if(add[now]){//加值标记sum[now<<1]+=add[now]*ln;sum[now<<1|1]+=add[now]*rn;add[now<<1]+=add[now];add[now<<1|1]+=add[now];mx[now<<1]+=add[now];mi[now<<1]+=add[now];mx[now<<1|1]+=add[now];mi[now<<1|1]+=add[now];add[now]=0;}return ;
}
void update_add(int now,int l,int r){if(L<=l&&r<=R){add[now]+=v;sum[now]+=v*(r-l+1);mx[now]+=v;mi[now]+=v;return ;}int mid=(l+r)>>1;down(now,mid-l+1,r-mid);if(L<=mid)update_add(now<<1,l,mid);if(mid<R)update_add(now<<1|1,mid+1,r);up(now);return ;
}
void update_set(int now,int l,int r){if(L<=l&&r<=R){set[now]=v;sum[now]=v*(r-l+1);add[now]=0;mx[now]=v;mi[now]=v;return ;}int mid=(l+r)>>1;down(now,mid-l+1,r-mid);if(L<=mid)update_set(now<<1,l,mid);if(mid<R)update_set(now<<1|1,mid+1,r);up(now);return ;
}
Tmp query(int now,int l,int r){if(L<=l&&r<=R){return Tmp(sum[now],mx[now],mi[now]);//十分方便}int mid=(l+r)>>1;down(now,mid-l+1,r-mid);Tmp tmp;int sum=0,mx=-inf,mi=inf; if(L<=mid){tmp=query(now<<1,l,mid);sum+=tmp.sum;mx=max(mx,tmp.mx);mi=min(mi,tmp.mi);}if(mid<R){tmp=query(now<<1|1,mid+1,r);sum+=tmp.sum;mx=max(mx,tmp.mx);mi=min(mi,tmp.mi);}//  up(now);        //然而并不用up()tmp.sum=sum,tmp.mi=mi,tmp.mx=mx;return tmp;
}
template <class T>inline void read(T &x){x=0;int ne=0;char c;while(!isdigit(c=getchar()))ne=c=='-';x=c-48;while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
int main()
{int op,x1,x2,y1,y2;read(r),read(c),read(m);// build(1,1,r*c);while(m--){read(op),read(x1),read(y1),read(x2),read(y2);     if(op==1){read(v);for(register int i=x1;i<=x2;i++){ L=(i-1)*c+y1,R=(i-1)*c+y2;   //注意处理技巧!!!update_add(1,1,r*c);  //r*c是所有元素的范围}}else if(op==2){read(v);for(register int i=x1;i<=x2;i++){L=(i-1)*c+y1,R=(i-1)*c+y2;   //注意处理技巧!!!update_set(1,1,r*c);}}else {Tmp tmp;int sum=0,mx=-inf,mi=inf;for(register int i=x1;i<=x2;i++){L=(i-1)*c+y1,R=(i-1)*c+y2;   //注意处理技巧!!!tmp=query(1,1,r*c);sum+=tmp.sum;mx=max(mx,tmp.mx);mi=min(mi,tmp.mi);}printf("%d %d %d\n",sum,mi,mx);}}return 0;
}

转载于:https://www.cnblogs.com/Rye-Catcher/p/8971634.html

luogu题解 UVA11992 【Fast Matrix Operations】相关推荐

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

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

  2. Fast Matrix Operations

    uva11992:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_prob ...

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

    主体段树,要注意,因为有set和add操作,当慵懒的标志下推.递归优先set,后复发add,每次运行set行动add马克清0 WA了好几次是由于计算那一段的时候出问题了,可笑的是我对着模板找了一个多小 ...

  4. uva 11992 - Fast Matrix Operations

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

  5. uva 11992 Fast Matrix Operations

    这道题很狗血啊 赋值的时候那个v是大于等于0来着,主要考察区间赋值和更新,pushdown同时要有两个操作.代码如下: 1 #include<cstdio> 2 #include<c ...

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

    比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...

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

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

  8. 数学基础 - 矩阵的基本运算(Matrix Operations)

    矩阵的基本运算(Matrix Operations) 目录 矩阵的基本运算(Matrix Operations) 目录 三个初等行(列)变换 加法(Plus) 乘法(Multiply) 与数的乘法 与 ...

  9. Matrix operations

    本文为<Linear algebra and its applications>的读书笔记 目录 Sums and Scalar Multiples Matrix Multiplicati ...

  10. Fast Matrix Factorization for Online Recommendation with Implicit Feedback论文代码分析

    1 数据结构 userCount:用户数 itemCount:项目数 user_ratings:ArrayList<ArrayList>, 问:此处为什么要用二维数组? 答:第1维是用户, ...

最新文章

  1. 测试使用2mH的工字型电感在接收150kHz导航信号中性能
  2. sqlite库——C实现,给sqlite数据库添加信息并把信息写入文件,删除日志和库中的日志信息
  3. Kubernetes 网络概念及策略控制(叶磊)
  4. shell判断输入变量或者参数是否为空
  5. yum安装k8s集群(单master两个node、阿里云镜像源)
  6. OpenGL polygonsmooth多边形平滑的实例
  7. 如何查看正在使用某个端口的应该程序
  8. Java学习笔记2.1.3 Java基本语法 - Java关键字与标识符
  9. 再谈正态分布或高斯函数
  10. 特斯拉推出儿童版电动四轮越野摩托车
  11. 单元测试的思考与实践
  12. 正确解决:关于Lattic Diamond软件注册不成功(license问题)
  13. 手机邮箱无法显示加密邮件_电子邮件可能无法加密
  14. webservice 传输加密
  15. python笔记本电脑推荐2020_最新版:2020年适合程序员的推荐笔记本电脑
  16. uni-app升级方案
  17. 整理的一些代码优化细节
  18. 浦东朋友夏天的时间线
  19. access调整字段顺序_Microsoft Access中的顺序行
  20. CBTC系统标准: 1474.4---系统特点及应用

热门文章

  1. php 请求 响应,发送http响应后继续处理php
  2. 输入文字加下划线_Word下划线你知道多少?
  3. 手机qq和电脑qq怎么同步消息_怎么在QQ上把自己电脑上的文件传到QQ上??
  4. app.honeycomb.Shell$HomeActivity failed to start
  5. 传统城域网架构遇瓶颈 引入NFV成有效解法
  6. 浏览器控件JxBrowser V6.14大版本发布 | 注入CSS
  7. iOS设计模式之代理模式
  8. Material Dialogs
  9. “经历”重于“技术”
  10. HP大中华区总裁退休感言(孙振耀 )