关闭

hdu2795(线段树单点更新)

标签: 线段树数据结构
654人阅读 评论(0) 收藏 举报
分类:

题目链接:hdu2795

/*线段树单点更新,求区间最大值
题目大意:有一块板子,长宽分别为W,H,然后有n块1*w海报
让你把这n快海报贴在这块板子上,尽量往板子的上方贴,同一行尽量往板子的左边贴。
对于第i块海报如果能够贴下则输出能贴在第几行,否则输出-1。

思路:利用线段树求区间的最大值;
maxx表示区间内能贴的海报的最大宽度
建树的时候要注意,heigh的范围特别大
当heigh>=m(m是海报的数量),要用m来建树
*/
#include<cstdio>
#include<algorithm>
using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int N = 200005;
int sum[N<<2];//表示某行能贴的海报的宽度
void build(int wide, int l, int r, int rt)
{
    sum[rt] = wide;//初始化为wide,最开始板上未贴海报
    if(l == r) return ;
    int m = (l+r) >> 1;
    build(wide, lson);
    build(wide, rson);
}
void update(int num, int pos, int l, int r, int rt)
{
    if(l == pos && r == pos)
    {
        sum[rt] -= num;//该行贴上一个宽为num的海报
        return ;
    }
    int m = (l + r) >> 1;
    if(pos <= m) update(num, pos, lson);
    if(m < pos) update(num, pos, rson);
    sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);//更新父节点
}
int query(int num, int l, int r, int rt)
{
    if(sum[rt] < num) return -1;
    if(l == r) return l;
    int m = (l + r) >> 1;
    if(sum[rt<<1] >= num)
        return query(num, lson);
    else
        return query(num, rson);
}
int main()
{
	int i,n,heigh,wide,num;
	while(~scanf("%d%d%d",&heigh,&wide,&n))
	{
	    heigh = min(heigh, n);
	    build(wide, 1, heigh, 1);
	    while(n--)
	    {
	        scanf("%d",&num);
	        int pos = query(num, 1, heigh, 1);
	        if(pos == -1) printf("-1\n");
	        else
	        {
	            printf("%d\n",pos);
	            update(num, pos, 1, heigh, 1);
	        }
	    }
	}
	return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:129001次
    • 积分:3075
    • 等级:
    • 排名:第11292名
    • 原创:186篇
    • 转载:13篇
    • 译文:0篇
    • 评论:2条
    最新评论