hdu 2795 Billboard 线段树

看了一会题,终于把题意弄明白了,一块板子,上面贴一些海报,但是这些海报贴起来是有规律的。

板子的大小是  h *w,   海报的大小是  1*wi.

我每次都是选择最高的最左的地方贴,如果没有位置给我贴,那就输出-1。。(题意就是这个样子)

那么刚开始看这题,感觉用模拟,肯定会很墨迹,而且数据很大,可能得挂。。

后来参考了别人的代码(这几天线段树的练习好像都是参考代码啊啊~~~~):

是这个样一个思路:   线段树的叶子节点存板子的宽度也就是 W, 而线段树每个节点的区间就代表1-h。。

所以我总结出了一个玩意:(如果一个

问题要用线段树来解决,那么你首先得知道,线段树的叶子表示啥,线段树节点的区间表示啥,然后找到叶子与区间的某种关系,顺着这种关系来解决问题,基本上是通过递归)

附上代码

#include <iostream>
#define N 800000
using namespace std;
struct node
{
 int maxn,l,r;
}st[N];
int h,w,n;
void build(int v,int l,int r)
{
  st[v].l=l;
  st[v].r=r;
  st[v].maxn=w;
  if(l==r)return;
  int mid=(st[v].l+st[v].r)/2;
  build(2*v,l,mid);
  build(2*v+1,mid+1,r);
}
int find(int v,int d)
{
  if(st[v].maxn<d)return -1;
  if(st[v].l==st[v].r)
   {
    st[v].maxn=st[v].maxn-d;
    return st[v].l;
   }  
  int t=find(2*v,d);
  if(t==-1)t=find(2*v+1,d);
  if(t)
       st[v].maxn=max(st[v*2].maxn,st[v*2+1].maxn);
  return t;
}
int main()
{
 while(scanf("%d%d%d",&h,&w,&n)!=EOF)
 {
   if(h>n)h=n+100;
    build(1,1,h);  
  
   int temp;
   for(int i=0;i<n;i++)
   {
      scanf("%d",&temp);
      int s=find(1,temp); 
      printf("%d\n",s);
   }
   
 }
 
 return 0;  
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值