題目大意: 廣告牆高從上到下為h,寬左到右為w,還有n張廣告牌
用單位高度,寬度為wi的廣告牌去覆蓋牆
輸出廣告牌放的高度 (優先選擇最上面的,同一高度則放在最左邊),不放不下則輸出 -1
解題思路: 建立線段樹,區間表示每個高度的剩餘的寬度
最下層的結點(tree[t].left==tree[t].right),儲存這一層剩餘的寬度max
其他結點儲存左右子樹的剩餘寬度max
查詢的時候,當此結點的max大於廣告牌的寬度則往下查詢
當左右子樹都同時滿足的情況下,優先選擇左子樹,若發現max不滿足則停止搜尋這棵子樹
**:
#include #include #include #define max 210000
#define inf 0x3f3f3f3f
#define max(a,b) a>b?a:b
#define mid(a,b) (a+b)>>1
#define l(a) a<<1
#define r(a) (a<<1+1)
typedef structnode;
node tree[max<<2];
int n,h,w,pd,kk;
void build(int t,int l,int r) //以1為根節點建立[l,r]的線段樹
mid=mid(tree[t].left,tree[t].right);
build(l(t),l,mid);
build(r(t),mid+1,r);
tree[t].leftmax=tree[l(t)].max;
tree[t].rightmax=tree[r(t)].max;
tree[t].max=max(tree[t].leftmax,tree[t].rightmax);
}void query(int t,int l,int r,int m)
return ;
}mid=mid(tree[t].left,tree[t].right);
if(tree[t].max=m) //優先選擇滿足情況的左子樹
query(l(t),l,mid,m);
else if(tree[t].rightmax>=m) //左子樹不滿足,才選擇右子樹
query(r(t),mid+1,r,m);
else
return ;
tree[t].leftmax=tree[l(t)].max;
tree[t].rightmax=tree[r(t)].max;
tree[t].max=max(tree[t].leftmax,tree[t].rightmax);
}int main()
}return 0;
}
線段樹專題 HDU2795 Billboard
題意 給一塊h w廣告板,然後給n個1 wi的廣告條,廣告條放的順序是有限選擇向上的,再優先選擇左邊的,對於每塊廣告條,輸出它放的位置,如果放不下,輸出 1 分析 很簡單的單點更新max值的線段樹,思路很好想,以廣告板的每個高度建樹,更新點的時候優先選擇高度值小的點。注意 比較容易出錯的是 要注意h...
hdu 2795 單點更新
題意 有乙個公告欄,h m的,給定n個操作,對於每乙個操作給定乙個數wi,表示有乙個通知的大小是1 wi的,每次對於這種操作將這個通知放在盡可能上面盡可能左邊的位置中去。思路 有h行,將每一行初始為m,表示還有m個空位可以放,那麼運用一棵線段樹來記錄下,行之間的區間最大值,就是可以放下的最大值。對於...
hdu 2795 單點改動
題意 有h w大的公告板。有n條公告要寫入,每條公告高度都是1,寬度是wi,每次從最上最左的空位寫,假設有空位輸出第幾行。假設沒有足夠空位輸出 1。題解 注意h最大1e9。但事實上是看n的大小。由於假設有n條公告最多佔n行,所以線段樹最大是min h,n include include includ...