zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    十个经典排序算法
    筛选法求2000以内的10个以上连续非素数组
    算法学习路线
    git 文件重命名
    一个github账户多台电脑代码提交
    SQL起别名
    多个Python环境的构建:基于virtualenv 包
    git学习:忽略部分文件
    git学习:多人协作,标签管理
    git学习4:分支管理
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6222747.html
Copyright © 2011-2022 走看看