题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2795
一块 高度为h, 宽度为 w 的公告牌, 铁公告,公告 的高度一样,都是1, 宽度不同, 给你n个公告,下面n个宽度,如果这个公告能贴上,就 输出 贴在第几行,不能贴上, 输出- 1 . 注意:每个贴公告的人都尽量不想把公告贴到高处. 公告不能贴在别的上面
看数据规模, 公告牌的高度h和宽度w 均为 10^9, 最多有 n 200000个公告.
建树, 以每行为 叶子节点,建立 min(h,n) 个节点. 因为h > n有n个公告,最多占用n行, 父结点 记录 孩子节点的 最大剩余宽度, 更新即可
如果父结点记录 的是孩子节点 总共的 剩余量, 会TLE||~~||,想想为什么
#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> using namespace std; #define maxn 200005 struct Tree { int left, rignt, num; }node[maxn << 2]; int f; void BuildTree(int i, int num, int l, int r); void Update(int i, int num); int main() { int h, w, q; while(~scanf("%d %d %d", &h, &w, &q)) { int n = h < q ? h :q; BuildTree(1, w, 1, n); while(q--) { int len; f = 0; scanf("%d", &len); Update(1, len); if(f) printf("%d\n", f); else printf("-1\n"); } } return 0; } void BuildTree(int i, int num, int l, int r) { node[i].left = l; node[i].rignt = r; node[i].num = num; if(l == r) return; int mid = (l + r) >> 1; BuildTree(i << 1, num, l, mid); BuildTree(i << 1 | 1, num, mid + 1, r); } void Update(int i, int num) { //printf("i = %d\n", i); if(node[i].num < num) return; //if(f) return; if(node[i].left == node[i].rignt) { //printf("f = %d\n", f); f = node[i].left; node[i].num -= num; return; } Update(i << 1, num); if(!f) Update(i << 1 | 1, num); node[i].num = max(node[i << 1].num, node[i << 1 | 1].num); }