• HDU 2795 Billboard(区间求最大值的位置update的操作在query里做了)


    Billboard

    通过这题,我知道了要活用线段树的思想,而不是拘泥于形式, 就比如这题 显然更新和查询放在一起很简单 但如果分开写 那么我觉得难度会大大增加

    【题目链接】Billboard

    【题目类型】区间求最大值的位置update的操作在query里做了

    &题意:

    h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子

    &题解:

    思路:每次找到最大值的位子,然后减去L
    线段树功能:query
    区间求最大值的位置(直接把update的操作在query里做了)

    【时间复杂度】(O(nlogn))

    &代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 200000 + 9 ;
    int h,w,n;
    int seg[maxn<<2];
    inline void PushUp(int rt)
    {
    	seg[rt]=max(seg[rt<<1],seg[rt<<1|1]);
    }
    void Build(int b,int e,int rt)
    {
    	if (b==e){
    		seg[rt]=w;
    		return;
    	}
    	int m=b+e>>1;
    	Build(b,m,rt<<1);
    	Build(m+1,e,rt<<1|1);
    	PushUp(rt);
    }
    //把更新和查询放在了一起
    int Query(int xx,int b,int e,int rt)
    {
    	if (b==e){
    		seg[rt]-=xx;
    		return b;
    	}
    	int m=b+e>>1;
    	int re=0;
    	//这里保证了先从小的序号开始找
    	if (seg[rt<<1]>=xx)
    		re=Query(xx,b,m,rt<<1);
    	else
    		re=Query(xx,m+1,e,rt<<1|1);
    	PushUp(rt);
    	return re;
    }
    void Solve()
    {
    	while(~scanf("%d%d%d",&h,&w,&n)){
    		h=min(h,n);
    		Build(1,h,1);
    		for(int i=0;i<n;i++){
    			int t;
    			scanf("%d",&t);
    			if (seg[1]<t) puts("-1");
    			else {
    				printf("%d
    ",Query(t,1,h,1));
    			}
    		}
    	}
    }
    int main()
    {
    	Solve();
    	return 0;
    }
    
  • 相关阅读:
    2017《Java技术》预备作业 计科1501 杨欣蕊
    Java技术预备作业02杨欣蕊
    系统无法从光盘启动
    动态数组ArrayList的使用
    dbgrid数据显示和数据源不同
    异步任务判断服务器是否开启
    Java字符串格式化
    思科2960 监听端口设置
    64位win7安装jdk和eclipse
    Delphi临界区的使用
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6222747.html
Copyright © 2020-2023  润新知