HDU 2795 Billboard (线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795
题目大意:有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠左; 求每个广告的所在的位置,不能贴则为-1。
用线段树模拟,要是左子树的最大值比当前广告大,就查询更新左子树,否则就右子树。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int MAXN = 2e5 + 5; 6 struct segtree { 7 int l , r , val; 8 }T[MAXN << 2]; 9 int w , a[MAXN] , res; 10 11 void init(int p , int l , int r) { 12 T[p].l = l , T[p].r = r; 13 int mid = (l + r) >> 1; 14 if(l == r) { 15 T[p].val = w; 16 return ; 17 } 18 init(p << 1 , l , mid); 19 init((p << 1)|1 , mid + 1 , r); 20 T[p].val = max(T[p << 1].val , T[(p << 1)|1].val); 21 } 22 23 void query(int p , int val) { 24 if(T[p].l == T[p].r) { 25 T[p].val -= val; 26 res = T[p].l; 27 return ; 28 } 29 if(val <= T[p << 1].val) { 30 query(p << 1 , val); 31 } 32 else { 33 query((p << 1)|1 , val); 34 } 35 T[p].val = max(T[p << 1].val , T[(p << 1)|1].val); 36 } 37 38 int main() 39 { 40 int h , n; 41 while(~scanf("%d %d %d" , &h , &w , &n)) { 42 h = min(h , n); 43 init(1 , 1 , h); 44 for(int i = 0 ; i < n ; i++) { 45 scanf("%d" , a + i); 46 if(T[1].val < a[i]) 47 printf("-1\n"); 48 else { 49 query(1 , a[i]); 50 printf("%d\n" , res); 51 } 52 } 53 } 54 }