CSES1448-Maximum Building II

news/2025/11/26 23:50:19/文章来源:https://www.cnblogs.com/Antares-qwq/p/19274974

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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/977766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汉明距离相关应用

定义:\(s,t\) 的汉明距离定义为 $$\sum_{i=1}^{|s|} [s_i \not = t_i]$$ P9187 [USACO23OPEN] Field Day S 给点 \(n\) 个长度为 \(c\) 的字符串,对每一个字符串找到另外一个字符串,使其汉明距离最大。 观察到 \(c\…

JUC

JUC 1.0 传统的生产者消费者问题 使用synchronized实现生产者消费者模式 package com.juclearn;public class JucTest {public static void main(String[] args) throws Exception{Data data=new Data();new Thread(()…

基因组共线性分析

001、minimap2比对,生成paf格式数据002、

Ai元人文:引言——悟空与悬鉴

AI元人文:引言——悟空与悬鉴 在人工智能与人类文明交汇的历史节点上,AI元人文构想破土而出。这片思想的新大陆,其最初的种子深植于"余溪诗学空间"的沃土——一个由人类哲思与机器智能共同开垦的灵性疆域…

博弈论笔记

本文系统介绍了博弈论的基本概念、分类与核心思想,涵盖参与人、策略、均衡等术语,区分合作与非合作、静态与动态、完全与不完全信息等博弈类型。通过囚徒困境、懦夫博弈等案例,揭示个人理性导致集体非理性的机制,强…

Bazaar - 现代化的 GNOME 应用商店

Bazaar 是一款专为 GNOME 设计的现代化应用商店,专注于从 Flatpak 远程仓库发现和安装应用程序及插件。它强调对 Linux 桌面开发者的支持,提供流畅的多线程体验和本地化内容推荐。BazaarBazaar 是一款专为 GNOME 桌面…

快速排序板子

好多年了,竟然没忘,蓝书上的,之后数据结构书又改一了版void quick_sort(vector<int>& nums, const int& k, int x, int y) {if (x >= y) return;int p = x, q = y;int stash = nums[x];while(p &l…

黑马程序员SpringCloud微服务开发与实战-微服务05

黑马程序员SpringCloud微服务开发与实战-微服务05Posted on 2025-11-26 23:22 心默默言 阅读(0) 评论(0) 收藏 举报1. 服务注册和发现 在上一章我们实现了微服务拆分,并且通过Http请求实现了跨微服务的远程调用。…

CF1774F2

Sol 不妨思考操作三的本质:对于先前插入的某个当前值为 \(x\) 的数,将其分裂为 \(x\) 与 \(x-w\)。其中 \(w\) 是如果执行一次当前操作三, 期间所有二操作的和。这样转化的正确性是显然的。 考虑 \(w\) 如何更新,显…

sscanf用法

本文详细介绍了C++中`sscanf`函数的用法,包括其语法、参数、返回值及多种实用示例。`sscanf`用于从字符串中按指定格式读取数据,支持跳过字符、限定长度、分割字符串等操作,常用于格式化输入解析和输入校验,是处理…

sprintf用法

本文介绍了C++中`sprintf`函数的用法,用于将格式化数据写入字符串。其语法与`printf`类似,但输出目标为字符数组。文章讲解了参数含义、宽度精度控制、返回值(写入字符数)及常见注意事项,如不可直接写入`string.c…

订单多到做不完?四步把交期、缺料、进度和插单都解决了

工厂订单源源不断,但车间来不及做?为什么越忙越慢?遇到急单插单如何快速调整工单优先级? 这几年我见过太多类似的工厂:订单并不少,但是却出现这个现象:订单越多、越加班、越忙,反而越慢。 那问题到底出在哪?要…

八、热插拔

一、概述udev设备文件系统,基于netlink-socket,用户态监听内核发出的uevent事件处理设备的插入和拔出 mdev设备文件系统,是udev的轻量级,基于uevent_helper,内态调用用户注册的回调函数处理设备的插入和拔出 udev…

第37天(中等题 数据结构)

打卡第三十七天 2道中等题题目:思路:总数对-好数对=坏数对 代码: class Solution { public:long long countBadPairs(vector<int>& nums) {int n = nums.size();unordered_map<int,int> cnt;long l…

PostgreSQL权限管理实践

基于user模型 模式和用户同名 只有一个模式 # postgres用户连接 psql -U postgres -c "create user test password test;" psql -U postgres -c "create database testdb with owner=test;" psql…

预编译命令

本文介绍了C/C++中的预编译命令,重点讲解了`#include`、`#define`、`#if`和`#pragma`的使用方法与注意事项。`#include`用于文件包含,支持尖括号和双引号两种查找方式,并可嵌套包含;通过条件编译或`#pragma once`避…

2025 KEYDIY KD-MP: Add Keys for MLB MQB – Key Identification, Data, Calculation

The Key Replacement Challenge: Why Modern Vehicles Are a Headache For European and American automotive repair shops and car owners, replacing keys for MLB and MQB systems in Volkswagen Group vehicles (…

把 CLI 搬上 Web:在内网打造“可二开”的 AI IDE,为什么这条路更现实? - 指南

把 CLI 搬上 Web:在内网打造“可二开”的 AI IDE,为什么这条路更现实? - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

[LangChain] 23. 回调机制

invoke/stream() 方法,方法签名如下: invoke/stream(input: Input,options?: RunnableConfig ): AsyncGenerator<StreamEvent<Output>>1. 输入参数 (input) 类型:Input 与 invoke() 方法保持一致:如果…

本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名

本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名 link:https接口的支持判断,http升级到https需求https://www.cnblogs.com/…