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 200002 int 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); else ret = -1; //无法容纳 //wa了, 错误在于若总共只有一行, 第一次就是叶子结点, 而在叶子却没考虑是否可以容纳. pushup(e); //update return 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)); } } }