hdu2795 Billboard 线段树

题意:

给出一块h*w的广告牌,还有n张1*u的海报,海报尽量往上,左边的位置张贴,问每一张海报能贴的多高。

线段树单点修改。

注意:因为1 <= h,w <= 10^9; 1 <= n <= 200,000,但实际上,若h>n的话,最坏的情况下也只要用到前n行。

所以若h>n  则h=n

如果不加这一句,因为线段树的数组要开到h<<2这么大,又h<= 10^9,所以输入的h过大时会使开的数组过大。加了的话,就不会啦,n<<2是OK的。

 1 #include<cstdio>

 2 #include<algorithm>

 3 using namespace std;

 4 #define lson l,m,rt<<1

 5 #define rson m+1,r,rt<<1|1

 6 const int maxh=200010;

 7 int _max[maxh<<2];

 8 int ans;

 9 void pushup(int rt)

10 {

11     _max[rt]=max(_max[rt<<1],_max[rt<<1|1]);

12 }

13 void query(int u,int l,int r,int rt)

14 {

15     if(l==r){

16         _max[rt]-=u;

17         ans=l;

18         return ;

19     }

20     int m=(l+r)>>1;

21     if(_max[rt<<1]>=u)

22         query(u,lson);

23     else

24         query(u,rson);

25     pushup(rt);

26 }

27 int main()

28 {

29     int h,w,n;

30     while(scanf("%d%d%d",&h,&w,&n)!=EOF){

31         if(h>n)

32             h=n;

33         for(int i=1;i<=(h<<2);i++)

34             _max[i]=w;

35         int u;

36         for(int i=0;i<n;i++){

37             scanf("%d",&u);

38             if(_max[1]<u)

39                 printf("-1\n");

40             else{

41                 query(u,1,h,1);

42                 printf("%d\n",ans);

43             }

44         }

45     }

46     return 0;

47 }
View Code

 

你可能感兴趣的:(HDU)