标签:
Description
Input
Output
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\n"); 49 else printf("%d\n",Query(x,1,h,1)); 50 } 51 } 52 return 0; 53 }
标签:
原文地址:http://www.cnblogs.com/HDMaxfun/p/5693303.html