UVA 11992 线段树
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 线段树的更多相关文章
- UVa 11992 (线段树 区间修改) Fast Matrix Operations
比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...
- UVA 11992 ——线段树(区间修改)
解题思路: 将矩阵每一行建立一棵线段树,进而变成一维问题求解.注意数组要开 4*N 代码如下: #include <iostream> #include <cstdio> #i ...
- 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)的元素 ...
- uva 11525(线段树)
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 11297 线段树套线段树(二维线段树)
题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ...
- UVa 1400 (线段树) "Ray, Pass me the dishes!"
求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...
- uva 1513(线段树)
题目链接:1513 - Movie collection 题意:有一堆电影,按1-n顺序排,有m次操作,每次询问第ai个电影之前有多少个电影,然后将其抽出放在堆顶. 分析:线段树应用. 因为每次查询后 ...
- uva 12086 线段树or树状数组练习
题目链接 https://vjudge.net/problem/34215/origin 这个题就是线段树裸题,有两种操作,实现单点更新和区间和的查找即可,这里第一次学习使用树状数组完成. 二者相 ...
- UVa 12299 线段树 单点更新 RMQ with Shifts
因为shift操作中的数不多,所以直接用单点更新模拟一下就好了. 太久不写线段树,手好生啊,不是这错一下就是那错一下. PS:输入写的我有点蛋疼,不知道谁有没有更好的写法. #include < ...
随机推荐
- deepin2014.1快捷键
初试deepin2014.1,发现windows很多快捷键在deepin中也完美支持,举例如下: ctrl+shift+n : 新建文件夹 窗口键+E:打开文件系统 窗口键+TAB:3D切换桌面 al ...
- 自己写的POIUtil,主要解决从不同的HSSFWorkbook复制sheet以及根据单元格插入图片等
复制sheet的原始代码网上找的,但是小问题很多,然后自己动手改了一下: 根据单元格信息动态插入图片,如果单元格有文字,图片的位置会在文字之后,如果同样的位置已有图片则会往下插入. import or ...
- .Net Core 上传图片
/// <summary> /// 图片上传并存入数据库 /// </summary> /// <returns></returns> public J ...
- POJ 2083 Fractal 分形
去年校赛团队赛就有一道分形让所有大一新生欲生欲死…… 当时就想学了 结果一直拖到…… 今天上午…… 马上要省选了 才会一点基础分形…… 还是自己不够努力啊…… 分形主要是要找到递归点…… 还有深度…… ...
- digitalocean完成B轮8300万美元融资,赠送10美元优惠码
7月8日,美国vps服务商digitalocean在官方博客宣传,公司完成高达8300万美元B轮融资.融资方包括 IA Ventures, Andreessen Horowitz和Access Ind ...
- 为什么 dll 改名字之后无法使用
有人直接把dll名字改了,我的程序运行出错,说这是我程序的问题,难道真是这样吗? 总感觉直接改dll名字不对,但哪儿不对呢,带着这样的疑惑研究了一下,重新做了一下试验,结果程序抛出了错误: Could ...
- 洛谷-哥德巴赫猜想(升级版)-BOSS战-入门综合练习1
题目背景 Background 1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和.质数是指除了1和本身之外没有其他约数的数,如2和 ...
- Openjudge-计算概论(A)-鸡兔同笼
描述一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外).已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物输入第1行是测试数据的组数n,后面跟着n行输入.每组测试数 ...
- 正则匹配 sql语句参数
List<string> listcommand = new List<string>(); string sql = "update BMDMB set bmdmb ...
- Neutron网络性能测试与分析(一) CVR
测试环境:网络节点运行在Intel(R) Xeon(R) CPU E5-2630 v3服务器上,网卡使用intel的万兆卡82599ES 测试仪使用本人基于dpdk编写的程序,基本上可以打满万兆卡,小 ...