題意:
有乙個公告欄,h*m的,給定n個操作,對於每乙個操作給定乙個數wi,表示有乙個通知的大小是1*wi的,每次對於這種操作將這個通知放在盡可能上面盡可能左邊的位置中去。
思路:
有h行,將每一行初始為m,表示還有m個空位可以放,那麼運用一棵線段樹來記錄下,行之間的區間最大值,就是可以放下的最大值。
對於每乙個操作來說,盡可能的要放在上面,那麼也就是這個下標要盡可能的小,所以先判斷左兒子是否滿足區間最大值 >= 所要求的寬度wi,如果滿足的話遞迴的往左兒子找下去,直到找到葉子節點,更新該節點的值,減小wi;不滿足再找右兒子。 先找左兒子再找右兒子保證了盡可能放在上面。
注意:
第一發re。 然後發現此處的h是109
,那麼按道理來說不能開下這麼大的線段樹,但是會發現操作的次數n是比較小的,然後想一下不管怎麼樣最多隻需要n行的公告板就夠了。因為最壞情況每個操作都是給出m長度的,填充到最後乙個也才是n行。所以就只需要n就夠了。
感覺要多關注,這些之間的關係,有的時候題目中是有隱含的條件的orzz 還是太年輕了。
#include
#include
#include
#include
using
namespace
std;
#define m 200090
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int maxx[m<<2];
int h,m,n;
void pushup(int rt)
void build(int l,int r,int rt)
int m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}int query(int a,int l,int r,int rt)
int m = (l+r)>>1;
int ret;
if(maxx[rt<<1] >= a) ret = query(a,lson); //左兒子的區間最大值 >= a
else ret = query(a,rson);
pushup(rt);
return ret;
}int main()
}return
0;}
hdu 2795 單點改動
題意 有h w大的公告板。有n條公告要寫入,每條公告高度都是1,寬度是wi,每次從最上最左的空位寫,假設有空位輸出第幾行。假設沒有足夠空位輸出 1。題解 注意h最大1e9。但事實上是看n的大小。由於假設有n條公告最多佔n行,所以線段樹最大是min h,n include include includ...
HDU 2795 單點更新 區間最值
hdu 2795 這題有點特殊,要在查詢的時候更新,而且 因為是找最小的行數,所以非左即右,優先考慮左 存在解情況下 ac code include include include include includeusing namespace std define debug 0 define in...
HDU2795(線段樹 單點更新 思維)
題目鏈結 題目大意 給乙個h高,w寬的廣告牌,以及n條廣告的寬度,每條廣告的高度預設為1,問n條廣告能插上的話所在的最高行數,插入不了輸入 1.解題思路 比較容易到用mlen維護區間h能夠裝下的最長廣告的長度 未插入 n在2e5內,所以線段樹最多就開8e5就足夠了!之後單點更新的時候順帶返回下標。c...