[Code+#3]寻找车位

挺厉害的线段树题


m<=n,所以n<=2000,并且只有1000次修改询问,mqlogn的复杂度可以接受!

求全局?

对行(n)建一个线段树。

线段树中维护的东西,一定可以包含所有“完全包含在”这个横条中的最大正方形。

只在mid左、右的可以递归下去再取max,跨越中间的?

大小为1000的两个数组,维护区间两端的1000个位置的从左从右开始最长1的个数

线段树pushup的时候 考虑跨过mid的正方形

不妨考虑长方形 宽<=长 纵向下来的是宽,双指针l,r 横向的是长 不断往后走r 如果r-l+1>lsmin(l,r)+rsmin(l,r) 那么++l 保证宽小于等于长

(宽大于长的会在宽小的时候统计到) 相当于枚举对于r的时候,最靠上的宽小于等于长的位置l (因为ans取决于短边,也就是宽) 一定有单调性,所以l直接++即可 lsmin(l,r)+rsmin(l,r)额外用单调队列维护

子矩形?

先通过线段树把子矩形劈成logn段,就暂时消除了行宽的限制

直接做的话,对于完整的一个线段树区域,还要暴力枚举每个行中线的,就O(q*n^2logn)了

然鹅

对于每一个中线mid,设之前单调队列找到的边长是r[x][i],那么就是min(r[x][i],i-U+1)来贡献答案。(U,D是列的限制)

都是对i-U+1取min,那么r[x][i]一定就是选择最大的那一个。

所以,

每个区间再维护一个R[i],所有r[i]的max

这样保证了子矩形分到完整的区间的时候,可以直接做完return了。复杂度就能正确

对于query时往两侧都分治的区间,要再统计跨区间的最大正方形

这时最大1的长度就要和行的限制取min了。

queue用个pair存

代码:

(动态分内存)

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
il void rd(int &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=4e6+10;
int n,m,q;
int *lmx[4*N],*rmx[4*N],*ans[4*N];
int Pool[14*N],*cur=Pool,*mp[N];
struct que{int l,r;pair<int,int>q[N];
//    void p_f(int L){
//        while(l<=r&&q[l]<L) ++l;
//    }void push(int id,int v){while(l<=r&&q[r].se>v) --r;q[++r]=make_pair(id,v);}int get(int L){while(l<=r&&q[l].fi<L) ++l;if(l<=r) return q[l].se;else return -1;}void clear(){l=1,r=0;}
}Q1,Q2;
void pushup(int x,int l,int r){Q1.clear();Q2.clear();int j=1;for(reg i=1;i<=m;++i){Q1.push(i,rmx[ls][i]);Q2.push(i,lmx[rs][i]);while(i>=j&&Q1.get(j)+Q2.get(j)<i-j+1){++j;}ans[x][i]=i-j+1;}for(reg i=1;i<=m;++i){ans[x][i]=max(ans[x][i],max(ans[ls][i],ans[rs][i]));lmx[x][i]=(lmx[ls][i]==mid-l+1)?lmx[ls][i]+lmx[rs][i]:lmx[ls][i];rmx[x][i]=(rmx[rs][i]==r-mid)?rmx[rs][i]+rmx[ls][i]:rmx[rs][i];}
}
void build(int x,int l,int r){lmx[x]=cur;cur+=m+1;rmx[x]=cur;cur+=m+1;ans[x]=cur;cur+=m+1;if(l==r){for(reg i=1;i<=m;++i){ans[x][i]=rmx[x][i]=lmx[x][i]=mp[l][i];}return;}build(x<<1,l,mid);build(x<<1|1,mid+1,r);pushup(x,l,r);
}
void upda(int x,int l,int r,int p,int t,int c){if(l==r){ans[x][t]=rmx[x][t]=lmx[x][t]=c;return;}if(p<=mid) upda(x<<1,l,mid,p,t,c);else upda(x<<1|1,mid+1,r,p,t,c);pushup(x,l,r);
}
int mx;
void merge(int x,int l,int r,int L,int R,int U,int D){Q1.clear();Q2.clear();int j=U;for(reg i=U;i<=D;++i){Q1.push(i,min(mid-L+1,rmx[ls][i]));Q2.push(i,min(R-mid,lmx[rs][i]));while(i>=j&&Q1.get(j)+Q2.get(j)<i-j+1){++j;}mx=max(mx,i-j+1);}
}
void query(int x,int l,int r,int L,int R,int U,int D){if(L<=l&&r<=R){for(reg i=U;i<=D;++i){mx=max(mx,min(ans[x][i],i-U+1));}return;}if(L<=mid&&mid<R) {query(x<<1,l,mid,L,R,U,D);query(x<<1|1,mid+1,r,L,R,U,D);merge(x,l,r,L,R,U,D);}else if(L<=mid){query(x<<1,l,mid,L,R,U,D);}else{query(x<<1|1,mid+1,r,L,R,U,D);}
}int main(){rd(n);rd(m);rd(q);Q1.clear();Q2.clear();for(reg i=1;i<=n;++i){mp[i]=cur;cur+=m+1;for(reg j=1;j<=m;++j){rd(mp[i][j]);}}build(1,1,n);int x,y,l,s,r,t;int op;while(q--){rd(op);if(op==0){rd(x);rd(y);mp[x][y]^=1;upda(1,1,n,x,y,mp[x][y]);}else{mx=0;rd(l);rd(s);rd(r);rd(t);query(1,1,n,l,r,s,t);printf("%d\n",mx);}}return 0;
}}
signed main(){Miracle::main();return 0;
}/*Author: *Miracle*Date: 2019/2/13 21:22:39
*/

总结:
抓住m<=n性质,对长的n建线段树,区间维护信息时候,处理跨域mid的最大正方形。

灵活运用单调队列。

转载于:https://www.cnblogs.com/Miracevin/p/10372696.html

[Code+#3]寻找车位相关推荐

  1. java 寻找峰值峰谷_寻找峰值

    # # 寻找最后的山峰 # @param a int整型一维数组 # @return int整型 # class Solution: def solve(self , a ): # write cod ...

  2. 基于Android的车位共享系统的设计

    一.课题任务与目的 1. 课题背景         随着车辆越来越多,车位紧缺成为当前生活中最严重并且着急去解决的问题之一.本项目制作一款基于Android的车位共享系统用于缓解车位紧缺造成的压力.本 ...

  3. php汽车找车位,六款停车APP吐血实测 竟能找到免费停车场?

    没有买车之前,在公交车.地铁上挤得烦躁难耐,打车时看着车不动计价器依旧跳动感到无奈:但买车之后,烦心事又接踵而至,其中最让车主恼火的就是停车了.有车的人多了,停车位却不见增长,每天开车上班或开车到陌生 ...

  4. c语言单片机停车场收费系统,基于51单片机停车场车位引导系统设计

    ?周明彬 曾伊玲 摘要:在很多人流量大的地方,因为车辆集中的情况,所以每次经过停车场时都需要工作人员来指挥车辆,告诉车主停车场那些地方还有空余车位可以泊车.所以很多地方的旧停车场使用的管理方式,是十分 ...

  5. 共享车位|基于SpringBoot+vue+node共享车位平台的设计与实现

    作者主页:编程千纸鹤 作者简介:Java.前端.Pythone开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.面试技术整理.最新技术分享 收藏点赞不迷路  关注作者有好 ...

  6. 基于STM32单片机的智能停车场车位管理系统设计

    摘  要 通过调查发现,现有的许多公共场所的停车位管理落后,智能化程度不高.为顺应现代自动化狂潮的发展趋势,本项目以STM32单片机为主控芯片,基于RFID智能识别技术,设计了一个具有IC识别的智能停 ...

  7. 软件质量保证测试——共享车位

    一.需求文档 1.引言 1.1需求文档编写目的 本需求规格说明书对基于Web的共享车位管理系统进行简单的分析,系统的主要用户是行车车主,此文档可记录.整理出用户实现车位共享的业务流程和功能需求,描述用 ...

  8. 物联网智能车位锁的总体设计方案​

    目录 问题简述 物联网智能车位锁的总体设计方案 物联网智能车位锁 D型车位+车位锁控制系统模块 RFID感应车位锁,物联网云连网控制系统 RFID简介: 配套APP或者小程序 后台软件系统设计 车位引 ...

  9. 共享停车位小程序,微信小程序停车场车位,微信小程序停车场系统毕设作品

    项目背景和意义 目的:首先,在社会上"停车难"是一个众所周知的问题,每个小区,每个大厦都有自己的停车场,但是在没有进入停车场之前,我们没办法知道是否有空车位,空车位在哪个地方.为了 ...

  10. 基于JAVAEE的停车场管理系统(论文+PPT+源码

    详情介绍 毕业设计(论文) 论文题目 基于JAVAEE的停车场管理系统 Thesis Topic JAVAEE – based parking management system 毕业设计(论文)任务 ...

最新文章

  1. wp———跳转系统设置页面的wifi、网络连接、蓝牙、飞行模式等
  2. jenkins参数化构建过程
  3. VTK:颜色顶点标签用法实战
  4. datagrid wpf 刷新数据_c# – WPF Datagrid-自动刷新
  5. 拼写校正与动态规划的小故事
  6. jmeter提取mysql数据_通过jmeter读取数据库数据,并取值作为请求的入参
  7. php输入密码才能浏览,使用php为网页设置访问密码 - 小俊学习网
  8. 前端学习资料网址收集整理
  9. 通过消息跨进程发送与接收 TCopyDataStruct 数据 - 回复 skymesh
  10. std::thread的常用参数传递总结
  11. 【课程设计】图书管理系统 C语言版---操作系统版
  12. FileUtils工具类的使用
  13. 数字化、数字化营销及其重要性的思考
  14. 如何用计算机测量图片景深,用手机也能测景深 DOF Master景深测量软件
  15. 4G PCIE网卡在英创ESM6800上的使用步骤
  16. word批量调整图片大小
  17. 实现微信产品问题反馈群实时监控与问题自动录入(上)
  18. 大数据Hadoop之——Spark SQL+Spark Streaming
  19. N1文件服务器,n1盒子搭建ftp服务器
  20. 复盘暴涨,TWEE焕发第二春

热门文章

  1. Java服务器获取客户端的真实IP
  2. Aandroid调用摄像头拍照和从相册选择照片
  3. 大数据的学习——变量和数据类型
  4. 理解新型资本形式:用三层模型分析DeFi协议代币价值流
  5. Ubuntu进入root用户模式
  6. 2016NOIP普级组第一题--买铅笔(参考洛谷题解)
  7. 计算机网络:DHE详解
  8. 以空格分割字符串赋给数组(str可以是输入参数或echo)和read命令
  9. 京东、天猫的购物车的实现原理
  10. Power BI学习笔记(二)