HDU_2795 Billboard(线段树)

 

 /*题意:输出每次贴上的海报所在的行号,行号为1...h;

开始拿到这题没思路,后来问了问本校的大牛,终于找到思路。这题是按high建树,
结构体中定义一个len变量,存放当前该结点的空闲长度。某结点的父结点存放其子结
点的最大空闲长度值;

比如(len = 10):

1

len = max(len2,len3)

/   \

2 3

(len = max(len4,len5))

/ \ / \

4 5 6 7

(len = 6) (len = 7)

这样每次更新时,如果父结点的node[t].len < w,则父结点之下的结点都不符合条件,
可以跳过。
*/

/*My Code:*/

#include
<iostream>
#include
<cstdio>
#define L(t) t << 1
#define R(t) t << 1 | 1

using namespace std;

const int N = 200005;

struct node
{
int l, r;
int w;
}node[N
*4];

int w, ans;

void creat(int t, int l, int r)
{
node[t].l
= l;
node[t].r
= r;
node[t].w
= w;

if(l == r) return;
int mid = (l + r) >> 1;

creat(L(t), l, mid);
creat(R(t), mid
+1, r);
}

void updata(int t, int len)
{
if(node[t].l == node[t].r)
{
if(node[t].w < len)
return;

node[t].w
-= len;
ans
= node[t].l;
return;
}

if(len <= node[L(t)].w)
updata(L(t), len);

else
updata(R(t), len);

node[t].w
= node[L(t)].w > node[R(t)].w ? node[L(t)].w : node[R(t)].w;
}

int main()
{
//freopen("data.in", "r", stdin);

int h, n, i, b;
while(~scanf("%d%d%d", &h, &w, &n))
{
if(h > n) h = n; //注意这里,如果h>n则n以后的数都更新不到,最大建树建到n就可以。
creat(1, 1, h);
for(i = 1; i <= n; i++)
{
scanf(
"%d", &b);
ans
= 0;
updata(
1, b);
printf(
"%d\n", ans ? ans : -1);
}
}
return 0;
}

                   

原文地址:https://www.cnblogs.com/vongang/p/2178075.html