HDU 2796 线段树

来源:互联网 发布:地缘看世界 知乎 编辑:程序博客网 时间:2024/06/06 00:05

线段树单点更新

题意:

一个广告板,知道它的长和宽,现在有N条信息需要在板上显示,每天信息都有自己的宽度,长度都为1。现在问你每条信息在哪个位置。

思路:

利用线段树,将有多少条信息或者高度作为线段树的最大区间,然后题目中说明要如果不能放在最上边(topmost),那么就放在最左边的上边(leftmost)。现在以样例为准来说明,依据样例数据,那么线段树的区间为1~3,那么首先宽度为2的进来,然后放在1的位置,宽度为4的进来放在2的位置(因为1位置所剩宽度不够)。。。第一个宽度为3的进来,发现1位置还剩下3的宽度刚好够,于是把这条信息放在这里面。。。最后一个宽度为3的进来发现有问题,这时候没有空间可以用来放置了,于是输出-1.

注意点:

输入输出都要用格式化输入输出,还有就是如果是长度大于信息条数,那么按照信息条数作为线段树最大区间,反之。

#include<iostream>#include<fstream>#include<string>using namespace std;int H, W, N, T;#define maxn 200100#define Lchild rt<<1,L,m#define Rchild rt<<1|1,m+1,Rint tree[maxn * 4];void push_up(int rt){tree[rt] = tree[rt << 1] > tree[rt << 1 | 1] ? tree[rt << 1] : tree[rt << 1 | 1];}void build(int rt = 1, int L = 1, int R = T){if (L == R){tree[rt] = W;return;}int m = (L + R) >> 1;build(Lchild);build(Rchild);push_up(rt);}int update(int w, int rt = 1, int L = 1, int R = T){if (tree[rt] < w)return -1;if (L == R&&tree[rt] >= w){tree[rt] -= w;return L;}int m = (L + R) >> 1;int ret = -1;if (tree[rt << 1] >= w)ret = update(w, rt << 1, L, m);else if (tree[rt << 1 | 1] >= w)ret = update(w, rt << 1 | 1, m + 1, R);push_up(rt);return ret;}int main(){while (~scanf_s("%d%d%d", &H, &W, &N)){T = N > H ? H : N;build();int n;for (int i = 1; i <= N; i++){scanf_s("%d", &n);printf("%d\n", update(n));}}return 0;}


0 0
原创粉丝点击