hdu 2795 Billboard 线段树基础题
来源:互联网 发布:语音识别用到的算法 编辑:程序博客网 时间:2024/05/22 23:15
#include <stdio.h>#include <string.h>#define maxn 200000struct node{ int l,r,id,w;}e[maxn*4];int h,w,n;void build(int a,int b,int c){ e[c].l=a; e[c].r=b; e[c].id=a; e[c].w=w; if(a==b) return ; int mid=(a+b)/2; build(a,mid,2*c); build(mid+1,b,2*c+1);}int query(int val,int c){ //printf("%d %d %d %d\n",e[c].l,e[c].r,e[c].w,val); if(e[c].w<val) return -1; //printf("***\n"); if(e[c].l==e[c].r) return e[c].id; if(e[2*c].w>=val) return query(val,2*c); else return query(val,2*c+1);}void update(int a,int b,int c,int val){ if(e[c].l==a&&e[c].r==b) { e[c].w-=val; return; } int mid=(e[c].l+e[c].r)/2; if(b<=mid) update(a,b,2*c,val); else if(a>mid) update(a,b,2*c+1,val); if(e[2*c].w>e[2*c+1].w) { e[c].w=e[2*c].w; e[c].id=e[2*c].id; } else { e[c].w=e[2*c+1].w; e[c].id=e[2*c+1].id; }}int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF) { int i,j,k; if(h>n) h=n; build(1,h,1); for(i=0;i<n;i++) { scanf("%d",&k); int t; t=query(k,1); printf("%d\n",t); if(t!=-1) update(t,t,1,k); } } return 0;}/*以高度和广告数的较小值建线段树,树中w表示该段中最大空余量,id表示最大空余量所在行,从上还是记。每次贴广告比较空余量,从上到下,有空余就贴。再根据查找到的空余行进行点更新。*/