数据结构 线段树 HDU 2795Billboard(单点更新)

来源:互联网 发布:英雄杀今天探宝数据 编辑:程序博客网 时间:2024/05/16 09:16

题意:有h*w的 广告板子,现在要添加n次,的广告,每个广告宽度都为1,而且都只能横着放,依次输入每个广告的长度 x,问广告插入在哪一行,插不了输出-1

解法:线段树 ,单点更新,找还剩下的地方的最大值,update就直接在 query里进行了



#include <stdio.h>#include <string.h>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int N=222222;//一开始想不明白肯定会爆//n次放入可以放在重复层,而且 n 一定是小于等于h的 //再长的h也是浪费,所以最大用2X10^5,不用10^9int Max[N<<2]; int h,w,n;void PushUP(int rt){Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);}void build(int l,int r,int rt){Max[rt]=w;if(l==r) return ;int m=(l+r)>>1;build(l,m,rt<<1);build(m+1,r,rt<<1|1);}int query(int x,int l,int r,int rt){//x 新的一行 if(l==r){Max[rt]-=x;return l;//返回这一行 }int m=(l + r)>>1;int ret=0;// 如果 左边比 x大,往左走 if(Max[rt<<1]>= x)ret=query(x,l,m,rt<<1);else ret=query(x,m+1,r,rt<<1|1);PushUP(rt);return ret;}int main(){while(~scanf("%d%d%d",&h,&w,&n)){// n 为添加的长度,h为行数// n一定是小于等于h的可以减少很多没用的行数 if(h>n) h=n;build(1,h,1);while(n--){int x;scanf("%d",&x);// Max[1] 最大的一行的长度 if(Max[1]<x) printf("-1\n");else printf("%d\n",query(x,1,h,1));}}    return 0;}


0 0