鏈結
在蒜國的海岸線上有一排由西向東的瞭望塔,這些瞭望塔由於建造的地面高度不同,所有瞭望塔的高度也是不能不一樣的。
這個時候蒜國國王來問蒜頭君,每個瞭望塔向東能看到幾個瞭望塔?這裡需要注意在a塔東邊有b塔,b塔的高度高於或等於a塔的高度,那麼b塔後面的塔都看不到。
由題意知,求左邊第乙個大於或等於自身的數。
由單調棧的知識,只需維護乙個嚴格單調遞減的棧,即當前元素大於或等於棧頂元素時一直出棧,當前元素小於棧頂元素將當前元素直接進棧。每當乙個元素彈出的時候,那麼被彈出的元素,最遠可以看到的塔就是即將插入的塔,然後兩個位置做個差就可以了。
最後棧裡面剩餘的元素都是可以看到第 $n$個塔的(可假設$n+1$有乙個非常高的塔)
c++版
1 #include2c版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
1 #include2 #include3 #include4view code#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
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...