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;
}