题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795
题意:有一个h*w的黑板,有n张1*w的海报,每张海报尽量往上帖(最上面是1),同样高度则往左贴,输出每一张海报的高度,如果这张海报贴不上则输出-1
思路:开始想到了用高度建树,保存每一个高度还剩下多少w,但是没想到怎么查询……,应该尽量往左字树进行查询,直到一个高度可以容纳这张海报(就是tree[root].l == tree[root].r)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 200030 using namespace std; struct Tree { int l,r,date; }tree[maxn*3]; int h,w,res; void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; tree[root].date=w; if (l==r) return; int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); } void que(int root,int wei) { if (tree[root].l==tree[root].r) { tree[root].date-=wei; res=tree[root].l; return; } if (wei<=tree[root<<1].date) que(root<<1,wei); else if (wei<=tree[root<<1|1].date) que(root<<1|1,wei); tree[root].date=max(tree[root<<1].date,tree[root<<1|1].date); } int main() { int n; while (scanf("%d%d%d",&h,&w,&n)!=EOF) { if (h>n) h=n; build(1,1,h); for (int i=0;i<n;i++) { int wei; scanf("%d",&wei); res=0; if (tree[1].date>=wei) { que(1,wei); printf("%d\n",res); } else printf("-1\n"); } } }