好久没更题解了(改题困难的我)

题目描述

WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米;每列的高度单位也为米,由输入数据给出)。

使用刷子的规则是:

  • 与地面垂直,从栅栏的底部向上刷
  • 每次刷的宽度为M米(当剩余栅栏宽度不够M米的话,刷子也可以使用,具体看样例2)
  • 对于连续的M列栅栏,刷子从底向上,刷到的高度只能到这M列栅栏的最低高度。

WYT请你回答两个问题:

  • 最少有多少个单位面积不能刷到(单位面积为1平米)
  • 在满足第一问的条件下,最少刷几次?

输入格式

共两行:

第一行两个整数N和M。

第二行共N个整数,表示N列栅栏的高度

输出格式

一行,两个整数,分别为最少剩余的单位面积数量和最少刷的次数。

样例

输入

5 3
5 3 4 4 5

输出

3
2

样例对应解释



高度分别为 5 3 4 4 5 如上:

黄色的方块表示共有3个单位面积没刷上

绿色的框和红色的框表示一共刷了两次。

数据范围与提示

30%的数据:N<=10^3

50%的数据:N<=10^5

100%的数据:1<=N<=10^6, 1<=M<=10^6,N>=M, 每列栅栏的高度<=10^6.

思路

  • 这道题当时真的没有想出来,直接暴力模拟拿了点分,这道题的核心在于维护单调栈,用于求解每块木板向右(向左)延伸的长度,拿向右来说,我们维护单调递增的栈,当栈顶元素的长度小于要放入的元素,则正常入栈,top++,如果栈不为空且栈顶元素(假设为sta[top])大于扫描到的元素(假设为i),对栈顶元素执行出栈操作,然后可得sta[top]向右延伸的距离为r[sta[top]]=i-sta[top],r数组维护向右延伸的长度,同理可求得左边延伸长度;
  • 处理完l和r数组后,对于木板i,其延伸距离为l[i]+r[i]-1,判断其与刷子宽度的大小,大于则可以刷到,用flag标记,小于则不能。然后枚举每一块木板,维护mh数组为第i块木板能被刷到的长度,如果被标记过,则mh[i]=h[i],如果不能,则mh[i]=mh[i-1],用长度和减去可以被刷到的部分即为ans1;
  • 对于每一部分(能被刷到的的长度相等),贪心处理,用其宽度除以刷子宽度,累加得ans2;

附上代码一份

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long v[maxn],mh[maxn],sum,r[maxn],l[maxn];
long long n,m;
bool flag[maxn];
inline int read(){
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&& ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s;
}
long long sta[maxn],top,h[maxn];
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
h[i]=read();
sum+=h[i];
}
for(int i=1;i<=n+1;i++){
while(top && h[i]<h[sta[top]]){
r[sta[top]]=i-sta[top];
top--;
}
sta[++top]=i;
}
for(int i=n;i>=0;i--){
while(top && h[i]<h[sta[top]]){
l[sta[top]]=sta[top]-i;
top--;
}
sta[++top]=i;
}
for(int i=1;i<=n;i++){
if(l[i]+r[i]-1>=m)flag[i]=true;
}
for(int i=1;i<=n;i++){
if(flag[i])mh[i]=h[i];
else{
mh[i]=mh[i-1];
}
}
for(int i=n;i>0;i--){
if(!flag[i])mh[i]=max(mh[i],mh[i+1]);
sum-=mh[i];
}
cout<<sum<<endl;
long long k=2,ans=0;
while(k<=n+1){
int cnt=1;
while(k<=n+1 && mh[k]==mh[k-1]){
++cnt;
++k;
}
ans+=cnt/m;
if(cnt%m)++ans;
++k;
}
cout<<ans<<endl;
}

单调栈之WYT的刷子的更多相关文章

  1. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  2. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  3. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  4. poj 2559 Largest Rectangle in a Histogram - 单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19782 ...

  5. bzoj1510: [POI2006]Kra-The Disks(单调栈)

    这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...

  6. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

  7. 洛谷U4859matrix[单调栈]

    题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...

  8. POJ3250[USACO2006Nov]Bad Hair Day[单调栈]

    Bad Hair Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17774   Accepted: 6000 Des ...

  9. CodeForces 548D 单调栈

    Mike and Feet Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Subm ...

随机推荐

  1. PAT 挖掘机技术哪家强

    为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入格式: 输入在第 1 行给出不超过 105 的正整数 N,即参赛人数.随后 N  ...

  2. vscode的个人配置

    前言 此篇只是为了记录自己vscode的设置,防止以后配置丢失,无实际意义 { "files.autoSave": "afterDelay", "ed ...

  3. Python子类构造函数调用super().__init__()用法说明

    一.super的作用 1.如果子类(Puple)继承父类(Person)不做初始化,那么会自动继承父类(Person)属性name.2.如果子类(Puple_Init)继承父类(Person)做了初始 ...

  4. 学习Redis好一阵了,我对它有了一些新的看法

    前言 本篇文章不是一篇具体的教程,我打算记录一下自己对Redis的一些思考.说来惭愧,我刚接触Redis的时候只是简单地使用了一下,背了一些面试题,就在简历上写下了Redis这个技能点. 我们能在网络 ...

  5. kafka架构、基本术语、消息存储结构

    1.kafka架构 kafka处理消息大概流程 生产者发送消息给kafka服务器 消费者从kafka服务器(broker)读取消息 kafka服务器依靠zookeeper集群进行服务协调管理 2.ka ...

  6. Java——八种基本数据类型(常用类)

    装箱和拆箱 装箱:基本数据类型转为包装类 拆箱:包装类转为基本数据类型 jdk1.5(即jdk5.0)之后的版本都提供了自动装箱和自动拆箱功能 基本数据类型的包装类 举两个例子,看一下 public ...

  7. bug的描述

    我们知道了自身的症状,那么就从这里开始,一起聊一聊一个优秀的 BUG,应该包含哪些方面的内容呢? 标题 其实每一个 BUG 也都是一个小的文档,既然是文档,我们首先就要做好一个 “标题党”,当然,此 ...

  8. if test表达式逻辑判断不能用&&

    用&&会报错 用and 例如: <if test="age!=null and name!=null">

  9. [CentOS 7]挂载ntfs格式U盘

    在我们将U盘插入装有CentOS的系统时,经常会出现如图所示的错误提示.这是因为linux系统并不能兼容NTFS的文件系统.其解决方法如下(建议先进入root模式): 1.首先下载"ntfs ...

  10. Python在Linux下编译安装

    [准备环境] Linux centos [前言] 1 linux下默认带Python,带的是2.7版本的 ,如果需要升级版本,需要把系统的自带的Python改名或者卸载,再次安装你所需要的Python ...