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;
    }
    
  • 相关阅读:
    [HEOI2016/TJOI2016]求和——第二类斯特林数
    RMAN备份脚本
    CF724E Goods transportation
    RMAN备份脚本--DataGuard primary
    [CEOI2017]Mousetrap
    healthcheck
    [学习笔记]斯特林数
    database.sql
    HDU 4372 Count the Buildings——第一类斯特林数
    orac
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6222747.html
Copyright © 2011-2022 走看看