题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795
题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子
思路:每次找到最大值的位子,然后减去L,线段树区间求最值。
本题可以先Query再Update,也可以Query和Update一起来。后者明显要快一些:
//分开写
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <map> #include <queue> #include <algorithm> using namespace std; #define Maxn 200005 #define lx (x<<1) #define rx ((x<<1)| 1) #define MID ((l + r)>>1) int h,w,n; int A[Maxn]; int S[Maxn<<2]; void pushUp(int x) { S[x] = max(S[lx],S[rx]); } void build(int l,int r,int x) { if(l == r) { S[x] = w; return; } build(l,MID,lx); build(MID+1,r,rx); pushUp(x); } void update(int p,int d,int l,int r,int x) { if(l == r) { S[x] -= d; return; } if(p<=MID) update(p,d,l,MID,lx); else update(p,d,MID+1,r,rx); pushUp(x); } int query(int t,int l,int r,int x) { int ans = 0; if(l == r) { return l; } if(t<=S[lx]) ans = query(t,l,MID,lx); else ans = query(t,MID+1,r,rx); return ans; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int t; while(scanf(" %d %d %d",&h,&w,&n)!=EOF) { if(h>n) h = n; build(1,h,1); for(int i=0;i<n;i++) { scanf(" %d",&t); if(t>S[1]) puts("-1"); else { int temp = query(t,1,h,1); printf("%d\n",temp); update(temp,t,1,h,1); } } } return 0; }//Query中Update
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <map> #include <queue> #include <algorithm> using namespace std; #define Maxn 200005 #define lx (x<<1) #define rx ((x<<1)| 1) #define MID ((l + r)>>1) int h,w,n; int A[Maxn]; int S[Maxn<<2]; void pushUp(int x) { S[x] = max(S[lx],S[rx]); } void build(int l,int r,int x) { if(l == r) { S[x] = w; return; } build(l,MID,lx); build(MID+1,r,rx); pushUp(x); } int query(int t,int l,int r,int x) { int ans = 0; if(l == r) { S[x] -= t; return l; } if(t<=S[lx]) ans = query(t,l,MID,lx); else ans = query(t,MID+1,r,rx); pushUp(x); return ans; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int t; while(scanf(" %d %d %d",&h,&w,&n)!=EOF) { if(h>n) h = n; build(1,h,1); for(int i=0;i<n;i++) { scanf(" %d",&t); if(t>S[1]) puts("-1"); else printf("%d\n",query(t,1,h,1)); } } return 0; }