您的位置:首页 > 理论基础 > 计算机网络

http://acm.hdu.edu.cn/showproblem.php?pid=2795 更新节点构造线段数很关键,询问特殊

2010-08-16 20:47 555 查看
]/*
题意:有一个广告牌,高是h宽为w。现在要在上面贴纸条做广告,每个纸条都是单位长度的,
也就是h = 1;宽不一致!要求尽可能的往顶头贴,其次尽可能的往左边贴,
求给出规格的纸条能贴在广告牌上的第几行!(1 到 h)
然而 1 <= h , w <= 10^9 这个大的范围,如何线段树开不了那么大的数组
n <= 200000; 假设给我们n个数据都是1*w(w == 10^9),不是最多只能贴20000行么??
这个题目跟平常作的有点不一样的,询问很特殊
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL(x) ((x) << 1)
#define RR(x) ((x) << 1 | 1)
using namespace std;
const int N = 200005;
struct Seg_tree{
int l, r, start, size;
int mid(){
return (l + r) >> 1;
}
}tree[4 * N];
int h, w, row, n;
inline void Build(int l, int r, int node){
tree[node].l = l;
tree[node].r = r;
tree[node].start = 1;// 某行的没有贴东西的起始位置
tree[node].size = w;//某行贴完剩下的最大的空闲的空间
if(l == r){
return ;
}
int mid = (r + l) >> 1;
Build(l, mid, LL(node));
Build(mid + 1, r, RR(node));
}
inline void Query(int l, int r, int node, int size_w){
if(tree[node].size < size_w){
return ;
} // 如果该范围的行的最大剩余空闲 < size_w return
if(tree[node].l == tree[node].r){
tree[node].start += size_w;
tree[node].size -= size_w;
row = tree[node].r;
return ; // 找到第一满足条件的行
}
if(row != -1){// 如果已经找到满足条件的行 直接return
return ;
}
//int mid = tree[node].mid();
if(tree[LL(node)].size >= size_w){
Query(l, r, LL(node), size_w);
}
else{
Query(l, r, RR(node), size_w);
}
tree[node].size = max(tree[LL(node)].size, tree[RR(node)].size); // 记得跟新父节点剩余的最大空间
}
int main(){
while(scanf("%d %d %d", &h, &w, &n) != EOF){
if(h > n)
h = n;
Build(1, h, 1);
int tt;
while(n--){
scanf("%d", &tt);
row = -1;
Query(1, h, 1, tt);
printf("%d/n", row);
}
}
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tree query build struct