input

r c m      r<=20,1<=m<=20000

m行操作

1 x1 y1 x2 y2 v       add v

2 x1 y1 x2 y2 v       set v

3 x1 y1 x2 y2   查询该矩阵中的sum,max,min

output

对于每个3操作输出sum,max,min

做法:每行建一颗线段树

 #include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#define INF 0x7fffffff
#define MAX 1000000 using namespace std; struct node
{
int v,addv,setv,sum,min,max;
};
int r,c,m,x1,yy1,x2,yy2,v,op,suma,mina,maxa;
node a[][MAX*];
void pushdown(int &l,int &r,int &k,int&i)
{
if(a[i][k].setv==&&a[i][k].addv==) return;
int m=l+((r-l)>>),lc=k<<,rc=k<<|,allv=a[i][k].setv+a[i][k].addv;
if(a[i][k].setv) //有set操作时优先将set操作pushdown
{
a[i][lc].addv=a[i][rc].addv=a[i][k].addv;
a[i][lc].v=a[i][rc].v=a[i][lc].setv=a[i][rc].setv=a[i][k].setv;
a[i][lc].min=a[i][rc].min=a[i][lc].max=a[i][rc].max=allv;
a[i][lc].sum=(m-l+)*allv;
a[i][rc].sum=(r-m)*allv;
a[i][k].setv=a[i][k].addv=;
}
else //无set操作时只是add操作也要pushdown
{
a[i][lc].addv+=a[i][k].addv;
a[i][rc].addv+=a[i][k].addv;
a[i][lc].min+=a[i][k].addv;
a[i][rc].min+=a[i][k].addv;
a[i][lc].max+=a[i][k].addv;
a[i][rc].max+=a[i][k].addv;
a[i][lc].sum+=(m-l+)*a[i][k].addv;
a[i][rc].sum+=(r-m)*a[i][k].addv;
a[i][k].addv=;
}
// printf("l:%d r:%d setv:%d add:%d\n",l,r,a[i][k].setv,a[i][k].addv);
}
void reset(int &l,int &r,int &k,int&i)
{
int m=l+((r-l)>>),lc=k<<,rc=k<<|;
a[i][k].sum=a[i][lc].sum+a[i][rc].sum+(r-l+)*a[i][k].addv;
a[i][k].min=min(a[i][lc].min,a[i][rc].min)+a[i][k].addv;
a[i][k].max=max(a[i][lc].max,a[i][rc].max)+a[i][k].addv;
}
void setupdate(int l,int r,int k,int &i)
{
int lc=k<<,rc=k<<|;
if(yy1<=l&&yy2>=r)
{
a[i][k].min=a[i][k].max=a[i][k].setv=a[i][k].v=v;
a[i][k].addv=;
a[i][k].sum=(r-l+)*v;
//printf("l:%d r:%d setv:%d add:%d\n",l,r,a[i][k].setv,a[i][k].addv);
return;
}
pushdown(l,r,k,i);
int m=l+((r-l)>>);
if(yy1<=m) setupdate(l,m,lc,i);
if(yy2>m) setupdate(m+,r,rc,i);
reset(l,r,k,i);
}
void addupdate(int l,int r,int k,int &i)
{
int lc=k<<,rc=k<<|;
if(yy1<=l&&yy2>=r)
{
a[i][k].addv+=v;
a[i][k].sum+=(r-l+)*v;
a[i][k].min+=v;
a[i][k].max+=v;
return;
}
pushdown(l,r,k,i);
int m=l+((r-l)>>);
if(yy1<=m) addupdate(l,m,lc,i);
if(yy2>m) addupdate(m+,r,rc,i);
reset(l,r,k,i);
}
void query(int l,int r,int k,int& i,int add)
{
if(a[i][k].setv)
{
int allv=add+a[i][k].v+a[i][k].addv;
suma+=allv*(min(r,yy2)-max(l,yy1)+);
mina=min(mina,allv);
maxa=max(maxa,allv);
//printf("addv:%d all:%d %d %d\n",a[i][k].addv,add,mina,maxa);
return;
}
if(yy1<=l&&yy2>=r)
{
suma+=a[i][k].sum+(r-l+)*add;
mina=min(mina,a[i][k].min+add);
maxa=max(maxa,a[i][k].max+add);
return;
}
int m=l+((r-l)>>);
if(yy1<=m) query(l,m,k<<,i,add+a[i][k].addv);
if(yy2>m) query(m+,r,k<<|,i,add+a[i][k].addv);
}
int main()
{
freopen("/home/user/桌面/in","r",stdin);
while(scanf("%d%d%d",&r,&c,&m)==)
{
for(int i=;i<=r;i++) memset(a[i],,sizeof(a[][])**c);
//memset(a,0,sizeof(a));
while(m--)
{
scanf("%d%d%d%d%d",&op,&x1,&yy1,&x2,&yy2);
if(op==)
{
scanf("%d",&v);
for(int i=x1;i<=x2;i++) setupdate(,c,,i);
//for(int i=1;i<3*c;i++) printf("%d:%d %d\n",i,a[3][i].setv,a[3][i].addv);
//puts("set");
}
else if(op==)
{
scanf("%d",&v);
for(int i=x1;i<=x2;i++) addupdate(,c,,i);
//for(int i=1;i<3*c;i++) printf("%d:%d %d\n",i,a[3][i].setv,a[3][i].addv);
//puts("add");
}
else
{
suma=;
mina=INF;
maxa=-INF-;
//printf("row:%d-%d\ncol:%d-%d\n",x1,x2,yy1,yy2);
//for(int i=1;i<=r;i++) printf("rowsum:%d\n",a[i][1].sum);
for(int i=x1;i<=x2;i++) query(,c,,i,);
printf("%d %d %d\n",suma,mina,maxa);
}
}
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return ;
}

UVA 11992 线段树的更多相关文章

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

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

  2. UVA 11992 ——线段树(区间修改)

    解题思路: 将矩阵每一行建立一棵线段树,进而变成一维问题求解.注意数组要开 4*N 代码如下: #include <iostream> #include <cstdio> #i ...

  3. Fast Matrix Operations UVA - 11992 线段树

    题意翻译 有一个r行c列的全0矩阵,有以下三种操作. 1 X1 Y1 X2 Y2 v 子矩阵(X1,Y1,X2,Y2)的元素加v 2 X1 Y1 X2 Y2 v 子矩阵(X1,Y1,X2,Y2)的元素 ...

  4. uva 11525(线段树)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

  6. UVa 1400 (线段树) "Ray, Pass me the dishes!"

    求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...

  7. uva 1513(线段树)

    题目链接:1513 - Movie collection 题意:有一堆电影,按1-n顺序排,有m次操作,每次询问第ai个电影之前有多少个电影,然后将其抽出放在堆顶. 分析:线段树应用. 因为每次查询后 ...

  8. uva 12086 线段树or树状数组练习

    题目链接   https://vjudge.net/problem/34215/origin 这个题就是线段树裸题,有两种操作,实现单点更新和区间和的查找即可,这里第一次学习使用树状数组完成. 二者相 ...

  9. UVa 12299 线段树 单点更新 RMQ with Shifts

    因为shift操作中的数不多,所以直接用单点更新模拟一下就好了. 太久不写线段树,手好生啊,不是这错一下就是那错一下. PS:输入写的我有点蛋疼,不知道谁有没有更好的写法. #include < ...

随机推荐

  1. 读书笔记之C# delegate

    c#代理的使用主要在:需要将一个方法当做参数传递到另一个方法时. 比如启动一个线程执行任务,而这个线程要执行的方法可以通过代理传递过来. 代理包括一个方法或者多个方法的地址和C++的函数指针很相似,但 ...

  2. KindeEditor图片上传插件用法

    因业务需要找了款插件 KindeEditor编辑器确认挺好用,但无奈技术有限,上传配置不知,故问度娘! 图片上传对于部分新手来说有时候是一件非常头疼的事,今天来分享一下项目中使用到的这个插件Kinde ...

  3. 高精度之+×÷

    以下是三种高精度算术的模版: 高精度加法: ",s1,s2; ],ss2[],len; void dashu(string s1,int ss1[]) { ;i>=;i--) { ;j ...

  4. 一、链接Sql Server2014提示找不到实例的问题解决方案

    在登录数据库时,确认数据库地址.用户名.密码正确的情况下,却报如下错误,则说明目标数据库服务器有相应的服务未启动. 在目标数据库服务器中打开服务列表: 找到SQL Server(****)服务(括号中 ...

  5. aspose 解决插入html后字体问题

    /// <summary> /// 添加html /// </summary> /// <param name="strText"></p ...

  6. HTML URL编码参考(转载)

    URL编码(URL encoding)的作用是将字符转化为可在因特网上安全传输的格式.URL——统一资源定位符Web浏览器通过URL从Web服务器上请求页面.URL就是网页的地址,如:http://w ...

  7. Python 学习笔记10

    念念不忘,必有回响. 今天继续学习Python 类.

  8. js上拉跳转原理

    今天遇到一个需要上拉跳转的地方,其原理跟上拉加载有点类似,代码如下 window.onscroll = function(){ if(getScrollTop() + getClientHeight( ...

  9. RPC框架基本原理(一):服务注册

    什么是RPC框架 RPC整个过程涉及四类对象:客户端.客户端代理.服务端和服务端代理.RPC要求客户端和服务端之间约定好调用接口和传输格式(如JSON,Xml等),客户端在调用该接口时,由客户端的代理 ...

  10. hdu_3067_小t的游戏(脑洞)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3067 题意:中文,不解释 题解:一看就知道是要找规律的题,都是有循环节的,看代码. #include ...