又一个线段树,和前几个有点不太一样,这里的域值保存的是一个区间,或者说是一个长度,即能用的剩余空间。求的也不一样,求的是一个最靠近区间最端点符合条件的值。

struct node{
int l, r, sl, maxSize;
}st[NN
* 8];

sl保存的是那一排的首位置,maxSize表示当前区间的能用最大空间值。这题有四个学习的地方:

key1:当找到叶子节点,且有足够大的空间贴广告时,改变域值,返回。
key2:如果当前区间的最大可用空间都不够用时,即可return。
key3:如果已经找到合适的位置了,右半区间就不用再找了。
key4:每次回溯的时候,要把改变过的最大空间值maxSize,层层返回,层层更新。

 

代码
#include<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#define NN 200000

struct node{
int l, r, sl, maxSize;
}st[NN
* 8];
int h, w, n, row;

int Max(int a, int b){
return a > b ? a : b;
}

void Init(int l, int r, int id){
st[id].l
= l;
st[id].r
= r;
st[id].sl
= 1;
st[id].maxSize
= w;

if (r - l <= 1){
return ;
}

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

Init(l, mid, id
* 2);
Init(mid, r, id
* 2 + 1);
}

void Update(int key, int id){
//key1
if (st[id].r - st[id].l <= 1 && st[id].maxSize >= key){
row
= st[id].r;
st[id].sl
+= key;
st[id].maxSize
-= key;
return;
}
// key2
if (st[id].maxSize < key){
return;
}
int mid = (st[id].l + st[id].r) >> 1;

Update(key, id
* 2);
// key3
if (row == -1){
Update(key, id
* 2 + 1);
}

//key4
st[id].maxSize = Max(st[id * 2].maxSize, st[id * 2 + 1].maxSize);
}
int main()
{
int i, min;
while (scanf("%d%d%d", &h, &w, &n) != EOF){
if (h > n){
h
= n;
}
Init(
0, h, 1);
for (i = 1; i <= n; i++){
scanf(
"%d", &w);
row
= -1;
Update(w,
1);
printf(
"%d\n", row);
}
}
return 0;
}

 

posted on 2010-07-19 09:19  ylfdrib  阅读(457)  评论(0编辑  收藏  举报