给出一个高为h,宽为w的广告板,有n张广告需要贴,从第一行开始贴,尽量靠左,输出每个广告最后贴在哪一行的
先一直想不通这样建树是为什么
后来看到一篇题解里面的一句话“直到找到一个满足条件的叶子节点”
所以用min(h,n)建树,最后输出的为哪一行,即为一个单点(线段树的最末一层)
大概像这样
然后就是更新值,查询
1 #include <cstdio> 2 #include <ctime> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <stack> 10 #include <queue> 11 #include <string> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 17 18 typedef long long LL; 19 const double eps = 1e-8; 20 const int INF = (1 << 30) - 1; 21 const int maxn = 200005; 22 23 int a[maxn]; 24 struct node{ 25 int l,r,maxx; 26 }t[4*maxn]; 27 28 int n,w,h,x; 29 30 void Push_up(int p){ 31 t[p].maxx = max(t[p<<1].maxx,t[p<<1|1].maxx); 32 } 33 34 void Build_tree(int p,int l,int r){ 35 t[p].l = l; 36 t[p].r = r; 37 if(l == r) { 38 t[p].maxx = w; 39 return; 40 } 41 int mid = getmid(l,r); 42 Build_tree(p<<1,l,mid); 43 Build_tree(p<<1|1,mid+1,r); 44 Push_up(p); 45 } 46 47 int Query(int p){ 48 if(t[p].maxx < x) return -1; 49 if(t[p].l == t[p].r){ 50 t[p].maxx -= x; 51 return t[p].l; 52 } 53 int ans; 54 if(t[p<<1].maxx >= x) ans = Query(p<<1); 55 else ans = Query(p<<1|1); 56 Push_up(p); 57 return ans; 58 } 59 60 int main(){ 61 while(scanf("%d %d %d",&h,&w,&n) != EOF){ 62 Build_tree(1,1,min(n,h)); 63 for(int i = 1;i <= n;i++){ 64 scanf("%d",&x); 65 printf("%d ",Query(1)); 66 } 67 } 68 return 0; 69 }