尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

CSES1448-Maximum Building II

CSES1448-Maximum Building II
📅 发布时间:2026/6/23 6:09:01

Description

传送门
给你一个 \(n\times m\) 的森林地图,其中一些方格是空的,一些方格有树木。\(n,m \le 1000\)。
你想要在森林中放置一个 \(r \times c\) 的矩形建筑(\(1 \le r \le n,1 \le c \le m\))使得不需要砍伐任何树木。对于每对 \((r,c)\),计算有多少种放置方式。

Solution

整了一个思维难度较低的做法。

不是很会枚举右端点。考虑逐行扫描 + 单调栈,定义 \(h_i\) 为当前行第 \(i\) 列空白的最大高度,用单调栈维护 \(h\) 的后缀(严格)最小值。
设当前位于下标 \(cur\),对单调栈里的后缀最小值 \(h_i\),可以 \(O(1)\) 预处理 \([L_i,R_i]\) 表示 \([L_i,cur]\) 到 \([R_i,cur]\) 这些区间的最小值均为 \(h_i\)。(事实上 \(R_i=i\))
可以对每个下标 \(cur\) 枚举所有的后缀最小值 \(h_i\) 计算以 \(cur\) 为右边界的矩形(矩形高范围此时已确定),枚举矩形的左边界,那么对所有 \(r \in [1,h_i]\),\(c \in [cur-L_i+1,cur-R_i+1]\) 的 \((r,c)\) 均有 \(1\) 的贡献。使用二维差分即可做到 \(O(nm^2)\)。
给出代码实现:

top=0;
for(int j=1;j<=m;j++)
{while(top&&h[st[top]]>=h[j])top--;L[j]=st[top]+1,R[j]=j;st[++top]=j;for(int k=1;k<=top;k++)if(h[st[k]])ds[0].upd(1,h[st[k]],j-st[k]+1,j-L[st[k]]+1,1);
}

考虑拆出每个后缀最小值对答案的贡献,发现每次矩形加的行不变,列则类似滑动窗口向右移动。不妨在后缀最小值被 pop 出栈时计算答案。
对后缀最小值 \(i\),令 \(len=R_i-L_i+1\),将 \(i\) pop 出栈的下标为 \(Y\)。设 \(l\) 为矩形加最左边的一列,则有 \(1 \le l \le Y-i\)。
对每一列 \(x \in [1,Y-i+len-1]\) 考虑 \(i\) 的贡献,可以被计入答案的 \(l\) 需要满足 \(x-len+1 \le l \le x\)。分情况讨论:(只给出 \(len \le Y-i\) 的情况,\(len >Y-i\) 的情况见代码)

  1. \(1 \le x \le len-1\),此时 \(l \in [1,x]\),贡献为 \(x\)。
  2. \(len \le x \le Y-i\),此时 \(l \in [x-len+1,x]\),贡献为 \(len\)。
  3. \(Y-i \le x \le Y-i+len-1\),此时 \(l \in [x-len+1,Y-i]\),贡献为 \(Y-i+len-x\)。
    维护两个差分数组分别维护列的系数与常数项即可,时空复杂度 \(O(nm)\)。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
int h[N];struct dlt
{int pre[N][N];void clear(){for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)pre[i][j]=0;}void upd(int u,int d,int l,int r,int v){d++,r++;pre[u][l]+=v;pre[u][r]-=v;pre[d][l]-=v;pre[d][r]+=v;}void solve(){for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)pre[i][j]+=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];}
}ds[2];//差分数组int st[N],top;
int L[N],R[N];void update(int i,int Y)  //未知数与文字部分意义一致,可放心食用
{if(!h[i])return;int len=R[i]-L[i]+1;if(len<=Y-i){ds[1].upd(1,h[i],1,len-1,1);ds[0].upd(1,h[i],len,Y-i,len);ds[0].upd(1,h[i],Y-i+1,Y-i+len-1,Y-i+len);ds[1].upd(1,h[i],Y-i+1,Y-i+len-1,-1);}else{ds[1].upd(1,h[i],1,Y-i,1);ds[0].upd(1,h[i],Y-i+1,len-1,Y-i);ds[0].upd(1,h[i],len,Y-i+len-1,Y-i+len);ds[1].upd(1,h[i],len,Y-i+len-1,-1);}
}
int main()
{cin>>n>>m;ds[0].clear();ds[1].clear();for(int i=1;i<=n;i++){string s;cin>>s;for(int j=1;j<=m;j++)h[j]=(s[j-1]=='*')?0:h[j]+1;top=0;for(int j=1;j<=m;j++){while(top&&h[st[top]]>=h[j]){update(st[top],j);top--;}L[j]=st[top]+1,R[j]=j;st[++top]=j;// for(int k=1;k<=top;k++)if(h[st[k]])ds[0].upd(1,h[st[k]],j-st[k]+1,j-L[st[k]]+1,1);}while(top) //注意要把剩的后缀最小值计入答案{update(st[top],m+1);top--;}}ds[0].solve(),ds[1].solve();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cout<<ds[0].pre[i][j]+ds[1].pre[i][j]*j<<" ";cout<<"\n";}return 0;
}

相关新闻

  • 快速排序板子
  • CF1774F2
  • PostgreSQL权限管理实践

最新新闻

  • 2026手机制作红底证件照保姆级教程:免费换底色APP推荐
  • NAK蛋白在细胞信号转导与疾病中的研究进展
  • 我是如何通过“骚扰”开源作者解决了一个诡异Bug的
  • 轻量化同城搭子社交小程序|SpringBoot+UniApp 低配服务器秒部署,毕设 / 副业商用直接上线
  • Windows系统文件DAO350.DLL丢失找不到问题解决
  • Cesium高级教程-3D高斯泼溅-Splat-高斯数据渲染

日新闻

  • Arduino-ESP32项目深度解析:解锁隐藏芯片支持与架构演进
  • 2026年 系统窗厂家/品牌推荐榜单:隔音系统窗+高端系统门窗的核心优势与选购指南 - 品牌发掘
  • NVBench:首个双语非言语发声语音合成评测基准详解与实践

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号