UVA 11992 Fast Matrix Operations (降维)
2015-09-07 23:02
253 查看
题意:对一个矩阵进行子矩阵操作。
元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作。
一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后启发式建树复杂度是min(RlogC,ClogR)。
代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间。但是也有缺点,比如推区间结点数量的时候会麻烦一点。
元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作。
一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后启发式建树复杂度是min(RlogC,ClogR)。
代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间。但是也有缺点,比如推区间结点数量的时候会麻烦一点。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+1; int R,C; #define lid (id<<1) #define rid (id<<1|1) struct Seg { int add,setv; int Max,Min,sum; }tr[maxn<<2]; #define OP1(id,val)\ tr[id].add += val; tr[id].Max += val; tr[id].Min += val; tr[id].sum += (r-l+1)*val; #define OP2(id,val)\ tr[id].Max = tr[id].setv = tr[id].Min = val; tr[id].add = 0; tr[id].sum = val*(r-l+1); inline void push_down(int id,int l,int r) { int lc = lid, rc = rid, mid = (l+r)>>1; if(tr[id].setv>=0){ int &t = tr[id].setv; swap(r,mid); OP2(lc,t); swap(l,r); l++; swap(mid,r); OP2(rc,t); l--; swap(mid,l); t = -1; } if(tr[id].add>0){ int &t = tr[id].add; swap(r,mid); OP1(lc,t); swap(l,r); l++; swap(mid,r); OP1(rc,t); l--; swap(mid,l); t = 0; } } inline void maintain(int id) { int lc = lid, rc = rid; tr[id].sum = tr[lc].sum + tr[rc].sum; tr[id].Max = max(tr[lc].Max,tr[rc].Max); tr[id].Min = min(tr[lc].Min,tr[rc].Min); } int ql,qr,val; void add1D(int l = 0,int r = R*C-1,int id = 1) { if(ql<=l&&r<=qr) { OP1(id,val) return; } int mid = (l+r)>>1, lc = lid, rc = rid; push_down(id,l,r); if(ql<=mid) add1D(l,mid,lc); if(qr>mid) add1D(mid+1,r,rc); maintain(id); } void set1D(int l = 0,int r = R*C-1,int id = 1) { if(ql<=l&&r<=qr) { OP2(id,val) return; } int mid = (l+r)>>1, lc = lid, rc = rid; push_down(id,l,r); if(ql<=mid) set1D(l,mid,lc); if(qr>mid) set1D(mid+1,r,rc); maintain(id); } int queryMax1D(int l = 0,int r = R*C-1,int id = 1) { if(ql<=l&&r<=qr) { return tr[id].Max; } int mid = (l+r)>>1, lc = lid, rc = rid; push_down(id,l,r); int ret = 0; if(ql<=mid) ret = max(ret,queryMax1D(l,mid,lc)); if(qr>mid) ret = max(ret,queryMax1D(mid+1,r,rc)); return ret; } const int INF = 0x3f3f3f3f; int queryMin1D(int l = 0,int r = R*C-1,int id = 1) { if(ql<=l&&r<=qr) { return tr[id].Min; } int mid = (l+r)>>1, lc = lid, rc = rid; push_down(id,l,r); int ret = INF; if(ql<=mid) ret = min(ret,queryMin1D(l,mid,lc)); if(qr>mid) ret = min(ret,queryMin1D(mid+1,r,rc)); return ret; } int querySum1D(int l = 0,int r = R*C-1,int id = 1) { if(ql<=l&&r<=qr) { return tr[id].sum; } int mid = (l+r)>>1, lc = lid, rc = rid; push_down(id,l,r); int ret = 0; if(ql<=mid) ret += querySum1D(l,mid,lc); if(qr>mid) ret += querySum1D(mid+1,r,rc); return ret; } //[0,r) void add2D(int x1,int y1,int x2,int y2,int v) { val = v; int st = x1*C+y1, len = y2-y1; for(int x = x1; x <= x2; x++){ ql = st; qr = st+len; add1D(); st += C; } } void set2D(int x1,int y1,int x2,int y2,int v) { val = v; int st = x1*C+y1, len = y2-y1; for(int x = x1; x <= x2; x++){ ql = st; qr = st+len; set1D(); st += C; } } int querySum2D(int x1,int y1,int x2,int y2) { int ret = 0; int st = x1*C+y1, len = y2-y1; for(int x = x1; x <= x2; x++){ ql = st; qr = st+len; ret += querySum1D(); st += C; } return ret; } int queryMax2D(int x1,int y1,int x2,int y2) { int ret = 0; int st = x1*C+y1, len = y2-y1; for(int x = x1; x <= x2; x++){ ql = st; qr = st+len; ret = max(ret,queryMax1D()); st += C; } return ret; } int queryMin2D(int x1,int y1,int x2,int y2) { int ret = INF; int st = x1*C+y1, len = y2-y1; for(int x = x1; x <= x2; x++){ ql = st; qr = st+len; ret = min(ret,queryMin1D()); st += C; } return ret; } int main() { //freopen("in.txt","r",stdin); int m; while(~scanf("%d%d%d",&R,&C,&m)){ ql = 0; qr = R*C-1; val = 0; set1D(); while(m--){ int op,x1,y1,x2,y2; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2); if(op == 1){ int v; scanf("%d",&v); add2D(x1-1,y1-1,x2-1,y2-1,v); }else if(op == 2){ int v; scanf("%d",&v); set2D(x1-1,y1-1,x2-1,y2-1,v); }else { x1--;x2--;y1--;y2--; printf("%d %d %d\n",querySum2D(x1,y1,x2,y2),queryMin2D(x1,y1,x2,y2),queryMax2D(x1,y1,x2,y2)); } } } return 0; }
相关文章推荐
- openCobol 安装 windows下cobol执行环境做成
- Linux 系统时间和硬件时间
- centos 目录结构 快捷键 ls命令,alias别名,so:动态库 a:静态库,环境变量PATH,Ctrl+z 暂停命令,Ctrl+a 光标到行首,Ctrl+e 光标到行尾,Ctrl+u 删除光标前所有字符 Ctrl+r 搜索命 hash命令 Ctrl+左箭头/右箭头 cd命令 第三节课
- 在CentOS 6.3中安装拼音输入法
- Linux命令备忘实例(7)——双向重定向与字符操作
- opengl流水线
- linux--Xshell的使用
- linux--SSH Secure Shell Client
- 同一进程中的线程究竟共享哪些资源
- Linux-remote change password (more)
- linux运维实战练习-2015年9月5日课程作业
- Linux计划任务
- 刚安装的tomcat在 myeclipse中第一次启动时报错:Address already in use: JVM_Bind<null>:8080
- Apache FileUpload文件上传
- C++ 代码模拟登录淘宝、天猫、支付宝等电商网站的实现 分类: C/C++ 随笔杂文 2015-01-26 11:17 3787人阅读 评论(9) 收藏 举报 有关C++ 代码模拟登录淘宝、天猫、支
- linux shell中,单引号、 双引号,反引号(``),$()的区别
- linux shell中,单引号、 双引号,反引号(``),$()的区别
- Centos7 firewall常用命令总结
- Linux下磁盘常见错误分析与检测工具使用
- Linux内存管理之mmap详解