HDU 2795 HDOJ 2795 Billboard ACM 2795 IN HDU
Posted on 2010-09-26 22:15 MiYu 閱讀(1645) 評論(0) 編輯 收藏 引用 所屬分類: ACM ( 數(shù)據(jù)結構 ) 、ACM ( 線段樹 )MiYu原創(chuàng), 轉帖請注明 : 轉載自 ______________白白の屋
題目地址:
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
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.
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.
3 5 5 2 4 3 3 3
1 2 1 3 -1
一開始沒想明白怎么做 , 仔細想了想, 再次 讀題后 發(fā)現(xiàn) , n <= 200000; 也就是說 最多 也就 200000 條廣告 , 你就算每行貼一張 ,
最多也就貼到 200000 行, 所以 不要被 h <= 10^9 次方嚇到了 ,認為 線段樹開不了那么大的數(shù)組 . 只要開 200000 就可以了 .
其他的 沒什么 好說的 , 知道這個 就直接 暴 吧 ............將近 7000MS .=水過................. g++提交 還華麗的 送出了 一次 TLE....
C++ 水過了 ............
// 一直沒明白 為什么我的 代碼速度 那么 慢, 查詢后 更新 的時間是 2000MS 左右 , 我的 是 查詢 就更新了,
竟然要 將近 7000MS ? 非常 郁悶 , 不信邪的 繼續(xù) 檢查 代碼, 在 瞪了 1哥小時后 , 忽然想到 : 把 cout 改成
printf 會怎樣? 結果 : 1640 MS AC ..............鬼知道他的 數(shù)據(jù)量有多大..... cout 和 printf
竟然 差了 5000 MS 的時間 ...........無語
代碼如下 :
/*
Coded By : MiYu
Link : http://www.cnblogs.com/MiYu || http://www.shnenglu.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;
}