Billboard
Time Limit:8000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64uDescription
在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
每张广告都是高度为1宽度为wi的细长的矩形纸条。
贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。
如果没有合适的位置了,那么这张广告就不会被贴了。
现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。
Input
多组样例,不超过40个。
对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。
下面n行每行一个整数 wi (1 <= wi <= 10^9) - 第i张广告的宽度.
下面n行每行一个整数 wi (1 <= wi <= 10^9) - 第i张广告的宽度.
Output
对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。
Sample Input
3 5 5
2 4 3 3 3
Sample Output
1
2 1 3 -1
1 //线段树专题 2 //用父节点保存子节点剩余的最大的广告长度。
3 //AC代码如下:
1 #include"iostream" 2 #include"algorithm" 3 #include"cstdio" 4 #include"cstring" 5 #include"cmath" 6 #define max(a,b) a>b?a:b 7 #define min(a,b) a<b?a:b 8 #define lson l,m,rt<<1 9 #define rson m+1,r,rt<<1|1 10 using namespace std; 11 12 const int MX=300000+10; 13 int sum[MX<<2]; 14 int h,w; 15 16 void PushUp(int rt) { 17 sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); //更新节点 父节点为子节点里面广告牌剩余的最大的长度 18 } 19 20 void Build(int l,int r,int rt) { 21 sum[rt]=w; //每个节点标记为广告纸的最大宽度 22 if(r==l) return ; 23 int m=(r+l)>>1; 24 Build(lson); 25 Build(rson); 26 } 27 28 int Query(int x,int l,int r,int rt) { 29 if(l==r) { 30 sum[rt]-=x; //查询到满足条件,更新此节点广告位置的长度 31 return l; 32 } 33 int m=(r+l)>>1; 34 int ret=0; 35 if(sum[rt<<1]>=x) ret = Query(x,lson); //从满足条件的广告剩余宽度开始粘贴 36 else ret = Query(x,rson); //总是从左节点开始贴广告纸 37 PushUp(rt); 38 return ret; 39 } 40 int main() { 41 int n; 42 int x; 43 while(~scanf("%d%d%d",&h,&w,&n)) { 44 h=min(h,n); //【这样可以减少内存】多余的广告位不会使用到。 45 Build(1,h,1); //总共的子节点数为广告牌的高度 46 for(int qq=1; qq<=n; qq++) { 47 scanf("%d",&x); 48 if(sum[1]<x) printf("-1 "); 49 else printf("%d ",Query(x,1,h,1)); 50 } 51 } 52 return 0; 53 }