单调栈专题练习- # P2897 [USACO08JAN] Artificial Lake G
题目背景
USACO 2008 January Gold
题目描述
夏日那让人喘不过气的酷热将奶牛们的烦躁情绪推到了最高点。最终,FJ 决定建一个人工湖供奶牛消暑之用。为了使湖看起来更加真实,FJ 决定将湖的横截面建成 \(N(1\le N\le 100,000)\) 个连续的平台高低错落的组合状,所有的平台从左到右按 \(1\sim N\) 依次编号。当然咯,在湖中注入水后,这些平台都将被淹没。平台 \(i\) 在设计图上用它的宽度 \(W_i(1\le W_i\le1,000)\) 和高度(你可以理解为该平台顶离 FJ 挖的地基的高度)\(H_i(1\le H_i\le 1,000,000)\) 来描述的。所有平台的高度都是独一无二的。湖的边缘可以视为无限高的平台。下面给出了一张 FJ 的设计图:
* * :
* * :
* * 8
* *** * 7
* *** * 6
* *** * 5
* ********** 4 <- height
* ********** 3
*************** 2
*************** 1
Level | 1 |2| 3 |
按 FJ 的设想,在坑挖好后,他会以 \(1\) 单位每分钟的速度往最低的那个平台上注水。水在离开水管后立即下落,直到撞到平台顶或是更早些时候注入的水。然后,与所有常温下的水一样,它会迅速地流动、扩散。简单起见,你可以认为这些都是在瞬间完成的。FJ 想知道,对于每一个平台,它的顶部是从哪个时刻开始,与水面的距离至少为 \(1\) 单位长度。
WATER WATER OVERFLOWS
| |
* | * * | * * *
* V * * V * * *
* * * .... * *~~~~~~~~~~~~*
* ** * *~~~~** : * *~~~~**~~~~~~*
* ** * *~~~~** : * *~~~~**~~~~~~*
* ** * *~~~~**~~~~~~* *~~~~**~~~~~~*
* ********* *~~~~********* *~~~~*********
*~~~~********* *~~~~********* *~~~~*********
************** ************** **************
************** ************** **************
After 4 mins After 26 mins After 50 mins
Lvl 1 submerged Lvl 3 submerged Lvl 2 submerged
输入格式
第一行一个正整数 \(N\)。
下面 \(N\) 行,每行两个正整数 \(W_i,H_i\)。
输出格式
\(N\) 行,每行一个正整数,表示:对于每一个平台,它的顶部是从哪个时刻开始,与水面的距离至少为 \(1\) 单位长度。
输入输出样例 #1
输入 #1
3
4 2
2 7
6 4
输出 #1
4
50
26
题解
- 最低的位置为k,开始灌水。 Ans[i]=w[i]。
- 选择往左侧还是右侧流动,min(h[pre[k],nxt[k]), 可以与高度值低的平台合并。
- 用栈来维护:有水流过的平台。
#include <iostream>
#define LL long long
using namespace std;
int n;
int top,st[100002],nxt[100002],pre[100002],flg[100002];
bool F[100002];
LL T,Ans[100002],w[100002],h[100002];;
int main() {
cin>>n;
LL Min_h=1e9+2;int id=0;
for (int i=1;i<=n;i++) {
scanf("%lld%lld",&w[i],&h[i]);
if (h[i]<Min_h) Min_h=h[i],id=i;
}
h[0]=h[n+1]=1e9+1;
for (int i=1;i<=n+1;i++) pre[i]=i-1;
for (int i=0;i<=n;i++) nxt[i]=i+1;
top++;st[top]=id;flg[id]=1;
int cnt=0;
while (cnt!=n) {
int k=st[top];
if (h[pre[k]]<h[nxt[k]]) {
if (h[pre[k]]>h[k]) {
Ans[k]=T+w[k];T+=w[k]*(h[pre[k]]-h[k]);cnt++;
w[pre[k]]+=w[k];nxt[pre[k]]=nxt[k];pre[nxt[k]]=pre[k];flg[k]=-1;top--;
}
if (flg[pre[k]]==0) {top++;st[top]=pre[k];flg[pre[k]]=1;}
}
else {
if (h[nxt[k]]>h[k]) {
Ans[k]=T+w[k];T+=w[k]*(h[nxt[k]]-h[k]);cnt++;
w[nxt[k]]+=w[k];nxt[pre[k]]=nxt[k];pre[nxt[k]]=pre[k];flg[k]=-1;top--;
}
if (flg[nxt[k]]==0){top++;st[top]=nxt[k];flg[nxt[k]]=1;}
}
}
for (int i=1;i<=n;i++) cout<<Ans[i]<<endl;
return 0;
}

浙公网安备 33010602011771号