标签:输入格式 宽度 pos hid 图片 黄色 += include min
WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米;每列的高度单位也为米,由输入数据给出)。
使用刷子的规则是:
WYT请你回答两个问题:
共两行:
第一行两个整数N和M。
第二行共N个整数,表示N列栅栏的高度
5 3
5 3 4 4 5
3
2
10 3
3 3 3 3 3 3 3 3 3 3
0
4
7 4
1 2 3 4 3 2 1
4
4
高度分别为 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.
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10, INF = 0x3f3f3f3f;
struct Node {
int id;
long long high;
} sol[maxn], solmin[maxn], solmax[maxn];
long long height[maxn], f[maxn];
long long ans = 0;
int flag = 1, t = 0;
int n, m;
void get_min() {
for (int i = 1; i <= n; i++) {
while (flag <= t && sol[t].high >= height[i]) t--;
t++;
sol[t].id = i;
sol[t].high = height[i];
if (i >= m) {
if (sol[flag].id <= i - m)
flag++;
solmin[i].high = sol[flag].high;
solmin[i].id = sol[flag].id;
}
}
for (int i = 1; i < m; i++) {
solmin[i].id = i;
solmin[i].high = -INF;
}
}
void get_max() {
flag = 1, t = 0;
for (int i = 1; i <= n; i++) {
while (flag <= t && solmax[t].high <= solmin[i].high) t--;
solmax[++t].id = i;
solmax[t].high = solmin[i].high;
if (i >= m) {
if (solmax[flag].id <= i - m)
flag++;
f[i - m + 1] = solmax[flag].high;
ans += height[i - m + 1] - f[i - m + 1];
}
}
long long maxh = -INF;
for (int i = n; i > n - m + 1; i--) {
maxh = max(maxh, solmin[i].high);
f[i] = maxh;
ans = ans + height[i] - f[i];
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> height[i];
get_min();
get_max();
int last = 1, num = 1;
for (int i = 1; i <= n; i++) {
if (i - last + 1 > m || f[last] != f[i]) {
last = i;
num++;
}
}
cout << ans << endl << num << endl;
return 0;
}
标签:输入格式 宽度 pos hid 图片 黄色 += include min
原文地址:https://www.cnblogs.com/hellohhy/p/13221282.html