标签:
http://acm.hdu.edu.cn/showproblem.php?pid=2795
#include <cstdio> #include <cstring> using namespace std; #define N 200005 #define lson rt<<1,l,m #define rson rt<<1|1,m+1,r struct node { int value; }tree[N<<2]; /* 线段树 记得要用h和n的较小值来建树 思路比较难想:每个区间的value装的是该区间还能放下的最大长度 然后与输入进来的len进行比较 题意要求优先放左边,所以如果左儿子放得下优先放左儿子,不然看右儿子 然后要PushUp更新父节点信息 如果根节点即第一个节点放不下,即整棵树必定没有一个区间可以放得下该广告 */ void Build(int rt,int l,int r,int k) { tree[rt].value=k; if(l==r) return ; int m=(l+r)>>1; Build(lson,k); Build(rson,k); } int Query(int rt,int l,int r,int len) { int ans; if(l==r){ tree[rt].value-=len; return l; } int m=(l+r)>>1; //如果左边能放下,优先放左边,不然看右边能不能放下 if(tree[rt<<1].value>=len) ans=Query(lson,len); else ans=Query(rson,len); // tree[rt].value=max(tree[rt<<1].value,tree[rt<<1|1].value); //PushUp if(tree[rt<<1].value>=tree[rt<<1|1].value) tree[rt].value=tree[rt<<1].value; else tree[rt].value=tree[rt<<1|1].value; return ans; } int main() { int h,w,n; while(~scanf("%d%d%d",&h,&w,&n)){ if(h>n) h=n; Build(1,1,h,w); while(n--){ int len; scanf("%d",&len); if(tree[1].value<len) printf("-1\n"); else printf("%d\n",Query(1,1,h,len)); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/fightfordream/p/5658307.html