HDOJ-2795 Billboard [线段树][单点更新+单点查询+维护区间最值]

来源:互联网 发布:伦敦留学 知乎 编辑:程序博客网 时间:2024/06/06 19:30

8s时限
单点更新+单点查询(要用区间信息来找到那个点)
注意:对于维护区间最值的, 附加域直接当主域用, 因为叶节点的最值就是那个点的值


思路:
1/ 维护区间最左的还未满w的点, 若整个区间满了, 用-1表示
这样不行的, 试想若最左未满点若剩余量还是<wi, 那怎么找下一个未满点? 几种方法都会超时.
2/ 蒟蒻啊, 看了hh的博客才知道要维护区间最大值(剩余量).  那我就维护最小值(已有量)吧...这样不用build一次..
注意: 维护最大值的初衷就是为了能够判断某区间是否有希望放wi.


另, 这题我刚想开敲的时候看了下h<= 10^9 然后sb了下想, 离散化?, 卧槽, 真是sb了, 因为h必然只需要维护到n.
因为最多n个海报每个都占一行咯.....

敲完又wa了一次....因为没考虑一进去就是叶子结点, 而叶子结点那个没判断容量是否满足.

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<string>#include<vector>#include<map>#include<algorithm>using namespace std;inline int Rint() { int x; scanf("%d", &x); return x; }inline int max(int x, int y) { return (x>y)? x: y; }inline int min(int x, int y) { return (x<y)? x: y; }#define FOR(i, a, b) for(int i=(a); i<=(b); i++)#define FORD(i,a,b) for(int i=(a);i>=(b);i--)#define REP(x) for(int i=0; i<(x); i++)typedef long long int64;#define INF (1<<30)const double eps = 1e-8;#define bug(s) cout<<#s<<"="<<s<<" "//8s时限//单点更新+单点查询(要用区间信息来找到那个点)//注意:对于维护区间最值的, 附加域直接当主域用, 因为叶节点的最值就是那个点的值//思路://1/维护区间最左的还未满w的点, 若整个区间满了, 用-1表示//这样不行的, 试想若最左未满点若剩余量还是<wi, 那怎么找下一个未满点? 几种方法都会超时.//2/蒟蒻啊, 看了hh的博客才知道要维护区间最大值(剩余量).  那我就维护最小值(已有量)吧...这样不用build一次..//注意: 维护最大值的初衷就是为了能够判断某区间是否有希望放wi.//另, 这题我刚想开敲的时候看了下h<= 10^9 然后sb了下想, 离散化?, 卧槽, 真是sb了, 因为h必然只需要维护到n.//因为最多n个海报每个都占一行咯.....#define MAXN 200002int a[MAXN<<2];//已有量int W;void pushup(int e){a[e] =  min(a[e<<1], a[e<<1|1]);}int query(int w, int l, int r, int e)//更新跟查询和在一起{if(l==r){if(W-a[e]<w) return -1;//..........还是在外面判断比较好a[e] += w;return l;//返回 l, 表示位置}else{int ret;//因为回溯时要更新, 不能直接return , 故先把结果保存下来int mid = (l+r)>>1;if(W-a[e<<1] >= w)ret = query(w, l, mid, e<<1);else if(W-a[e<<1|1] >= w)ret = query(w, mid+1, r, e<<1|1);elseret = -1;//无法容纳//wa了, 错误在于若总共只有一行, 第一次就是叶子结点, 而在叶子却没考虑是否可以容纳.pushup(e);//updatereturn ret;}}int main(){int h, n;while(scanf("%d%d%d", &h,  &W, &n)!=EOF){memset(a, 0, sizeof(a));//线段1~min(h, n)h = min(h, n);REP(n){int w = Rint();//if(W-a[1] < w) puts("-1");//if(W-a[1<<1] < w && W-a[1<<1|1] < w) puts("-1");//else printf("%d\n", query(w, 1, h, 1));printf("%d\n", query(w, 1, h, 1));}}}


原创粉丝点击