瞭望塔 單調棧

2022-05-02 01:15:10 字數 1658 閱讀 2725

鏈結

在蒜國的海岸線上有一排由西向東的瞭望塔,這些瞭望塔由於建造的地面高度不同,所有瞭望塔的高度也是不能不一樣的。

這個時候蒜國國王來問蒜頭君,每個瞭望塔向東能看到幾個瞭望塔?這裡需要注意在a塔東邊有b塔,b塔的高度高於或等於a塔的高度,那麼b塔後面的塔都看不到。

由題意知,求左邊第乙個大於或等於自身的數

由單調棧的知識,只需維護乙個嚴格單調遞減的棧,即當前元素大於或等於棧頂元素時一直出棧,當前元素小於棧頂元素將當前元素直接進棧。每當乙個元素彈出的時候,那麼被彈出的元素,最遠可以看到的塔就是即將插入的塔,然後兩個位置做個差就可以了。

最後棧裡面剩餘的元素都是可以看到第 $n$個塔的(可假設$n+1$有乙個非常高的塔)

c++版

1 #include2

using

namespace

std;

34 typedef long

long

ll;5

const

int maxn = 1000000 + 10;6

intn, a[maxn];

78 stacks;

9int

index[maxn];

1011

void

solve()

1221

s.push(i);22}

2324

int tmp = 0;25

while(!s.empty())

2630

for(int i = 1;i <= n;i++) printf("

%d%c

", index[i], i == n ? '

\n': '');

31}3233

intmain()

34

c版

1 #include2 #include3 #include4

#define maxsize 1000010

5#define maxn 100001067

intdata[maxsize];

8int

top;

910 typedef long

long

ll;11

intn, a[maxn];

12int

index[maxn];

1314

void

initstack()

1518

19bool

stackempty()

2023

24void push(int

e)25

2930

void

pop()

3134

35int

gettop()

3639

40void

solve()

4149

push(i);50}

51while(!stackempty())

5256

for(int i = 1;i <= n;i++) printf("

%d%c

", index[i], i == n ? '

\n': '');

57}5859

intmain()

60

view code

bzoj1038 瞭望塔 半平面交

首先對於給定的折線求出可行區域的半平面交,可行區域指所有的點p的集合,滿足點p出發的射線可以在不與折線提前相交的前提下能夠到達折線上的每乙個點。然後就變成上面乙個折線y1,下面乙個折線y2,求y1 y2的最小值了。一次分段函式的差是分段函式,而顯然一次分段函式的最小值在端點取到。沒了。ac 如下 i...

ZJOI 2008 瞭望塔 半平面交

題意 給出乙個以n個點為輪廓的村莊,在村莊任意位置放乙個瞭望塔,使瞭望塔能看到村莊的所有位置,求瞭望塔最低高度。思路 考慮輪廓的每一條邊,要看到這條邊就必須在這條邊以上的乙個半平面內,因此求半平面交即可,樣例圖 不妨將半平面交與地面上的直線看成分段函式,分別為f x 與g x 則所求即為h x f ...

ZJOI2008 瞭望塔 半平面交

題意 給出乙個以n個點為輪廓的村莊,在村莊任意位置放乙個瞭望塔,使瞭望塔能看到村莊的所有位置,求瞭望塔最低高度。只我們發現只有這個點在每個直線所在半平面以上的時候才能看到,如樣例圖 還注意到,只有在原圖的端點或半平面交的端點處才會更新答案。include include include includ...