HDU 2795 HDOJ 2795 Billboard ACM 2795 IN HDU


MiYu原创, 转帖请注明 : 转载自 ______________白白の屋    

 

题目地址:

 http://acm.hdu.edu.cn/showproblem.php?pid=2795

题目描述:

Billboard

Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 733    Accepted Submission(s): 340


Problem Description
At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, changes in the dining room menu, and other important information.

On September 1, the billboard was empty. One by one, the announcements started being put on the billboard.

Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi.

When someone puts a new announcement on the billboard, she would always choose the topmost possible position for the announcement. Among all possible topmost positions she would always choose the leftmost one.

If there is no valid location for a new announcement, it is not put on the billboard (that's why some programming contests have no participants from this university).

Given the sizes of the billboard and the announcements, your task is to find the numbers of rows in which the announcements are placed.
 

Input
There are multiple cases (no more than 40 cases).

The first line of the input file contains three integer numbers, h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the billboard and the number of announcements.

Each of the next n lines contains an integer number wi (1 <= wi <= 10^9) - the width of i-th announcement.
 

Output
For each announcement (in the order they are given in the input file) output one number - the number of the row in which this announcement is placed. Rows are numbered from 1 to h, starting with the top row. If an announcement can't be put on the billboard, output "-1" for this announcement.
 

Sample Input
        
       
       
       
3 5 5 2 4 3 3 3
 

Sample Output
        
       
       
       
1 2 1 3 -1
 

 

一开始没想明白怎么做 ,  仔细想了想,   再次 读题后 发现 , n <= 200000;  也就是说  最多 也就 200000 条广告 , 你就算每行贴一张 ,

最多也就贴到 200000 行,  所以  不要被  h <= 10^9  次方吓到了  ,认为 线段树开不了那么大的数组  . 只要开 200000 就可以了 .

 

其他的 没什么 好说的 , 知道这个 就直接 暴 吧 ............将近 7000MS .=水过.................   g++提交 还华丽的 送出了 一次 TLE....

C++  水过了 ............

 

//    一直没明白 为什么我的 代码速度 那么 慢,  查询后 更新 的时间是 2000MS 左右  , 我的 是 查询 就更新了,

竟然要 将近 7000MS ? 非常 郁闷 ,  不信邪的 继续 检查 代码, 在 瞪了 1哥小时后 , 忽然想到 : 把 cout 改成

printf 会怎样?   结果 :  1640 MS  AC ..............鬼知道他的 数据量有多大..... cout 和 printf

竟然 差了 5000 MS 的时间 ...........无语

代码如下 :

 

 /*

Coded By  : MiYu

Link      : http://www.cnblogs.com/MiYu  || http://www.cppblog.com/MiYu

Author By : MiYu

Test      : 1

Program   : 2795

*/

//#pragma warning( disable:4789 )

#include <iostream>

#include <algorithm>

#include <string>

#include <set>

#include <map>

#include <utility>

#include <queue>

#include <stack>

#include <list>

#include <vector>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

using namespace std;


struct ADV {

       int left, right, val;

       int mid () { return ( left + right ) >> 1; }     

}adv[800000];

int N, W, H, w;

void creat ( int l, int r, int rt = 1 ){

     adv[rt].left = l;

     adv[rt].right = r;

     adv[rt].val = W;

     if ( l == r )

        return ;

     int mid = adv[rt].mid();

     creat ( l, mid, rt << 1 );

     creat ( mid + 1, r, ( rt << 1 ) + 1 );

}

void add ( int rt = 1, int wei = w ){

    if ( wei <= adv[rt].val ){

         if ( adv[rt].left == adv[rt].right ){

              adv[rt].val -= wei;

              //cout << adv[rt].left << endl;  //杯具的 地方

printf ( "%d\n", adv[rt].left ); 

              return ;     

         } else if ( adv[rt<<1].val >= wei ) {

                add ( rt << 1 );

                adv[rt].val = max ( adv[rt<<1].val, adv[(rt<<1)+1].val );     

         } else {

                add ( ( rt << 1 ) + 1 );

                adv[rt].val = max ( adv[rt<<1].val, adv[(rt<<1)+1].val );        

         }   

    } else {

           //cout << -1 << endl;      //杯具的地方

puts ( "-1" );   

    }   

}

inline bool scan_ud(int &num)

{

    char in;

    in=getchar();

    if(in==EOF) return false;

    while(in<'0'||in>'9') in=getchar();

    num=in-'0';

    while(in=getchar(),in>='0'&&in<='9'){

        num*=10,num+=in-'0';

    }

    return true;

}

int main ()

{

    while ( scan_ud (H)&&scan_ud (W)&&scan_ud (N) ) {

           if ( H > 200000 )

               H = 200010;

           creat ( 1, H );

           for ( int i = 1; i <= N; ++ i ) {

                scan_ud (w);

                add ( );     

           }      

    }

    return 0;

}

 

 

 

 

另 附上 傻崽  神牛 代码 :

 

#include <iostream>

#include <algorithm>

#include <string>

#include <set>

#include <map>

#include <utility>

#include <queue>

#include <stack>

#include <list>

#include <vector>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#define FF(i,a) for( int i = 0 ; i < a ; i ++ )

#define FOR(i,a,b) for( int i = a ; i < b ; i ++ )

#define LL(a) a<<1

#define RR(a) a<<1|1

template<class T> inline void checkmin(T &a,T b) {if(a < 0 || a > b)a = b;}

template<class T> inline void checkmax(T &a,T b) {if(a < b) a = b;}

using namespace std;

struct Node {

int val;

int idx;

friend bool operator < (Node a , Node b) {

if(a.val == b.val) {

return a.idx > b.idx;

}

return a.val < b.val;

}

}error;

 

struct Seg_Tree{

int left,right;

Node node;

int mid() {

return (left + right)>>1;

}

}tt[800000];

 

int n , h , m;

 

void build(int l,int r,int idx) {

tt[idx].left = l;

tt[idx].right = r;

tt[idx].node.idx = l;

tt[idx].node.val = h;

if(l == r) return ;

int mid = tt[idx].mid();

build(l,mid,LL(idx));

build(mid+1,r,RR(idx));

}

 

void update(int l,int r,int val,int idx) {

if(l <= tt[idx].left && r >= tt[idx].right) {

tt[idx].node.val += val;

return ;

}

int mid = tt[idx].mid();

if(l <= mid) update(l,r,val,LL(idx));

if(mid < r) update(l,r,val,RR(idx));

tt[idx].node = max(tt[LL(idx)].node,tt[RR(idx)].node);

}

 

Node query(int w,int idx) {

if(tt[idx].node.val < w) {

return error;

}

if(tt[idx].left == tt[idx].right) {

return tt[idx].node;

}

if(tt[LL(idx)].node.val >= w) {

return query(w,LL(idx));

} else {

return query(w,RR(idx));

}

}

 

int main() {

error.idx = -1;

while(scanf("%d%d%d",&n,&h,&m) == 3) {

checkmin(n,m);

build(1,n,1);

while(m --) {

int w;

scanf("%d",&w);

Node ret = query(w,1);

printf("%d\n",ret.idx);

if(ret.idx != -1) {

update(ret.idx,ret.idx,-w,1);

}

}

}

return 0;

 

 

你可能感兴趣的:(HDU 2795 HDOJ 2795 Billboard ACM 2795 IN HDU)