1. 程式人生 > 實用技巧 >hdu 2795 Billboard 線段樹

hdu 2795 Billboard 線段樹

題目連結:Billboard

題意:

給你一個高度為h,寬為w的廣告牌。你有n個廣告,你需要把它們貼到廣告牌上面

每一個廣告的高度為1,寬度為vi

你要儘可能把廣告往上面貼(也就是高度往1這個數字靠近),而且廣告要儘可能的向左邊靠近

如果一個廣告可以貼到廣告牌上面就輸出高度,否則輸出-1

題解:

題目上面說了廣告要儘可能向上和左,那麼我們可以維護一下廣告牌每一行還有多少空閒的寬度

然後你發現h的大小是1e9,但是實際上不需要這麼大,因為n的大小是200000,最多也就是每一個廣告佔一行,所以h最大就是200000

程式碼:

#include<stdio.h>
#include<string
.h> #include<iostream> #include<algorithm> using namespace std; const int maxn=2e5+10; const int INF=0x3f3f3f3f; #define lson root<<1 #define rson (root<<1)|1 #define ll long long #define mem(a) memset(a,0,sizeof(a)) #define mem_(a) memset(a,-1,sizeof(a)) #define mem__(a) memset(a,INF,sizeof(a)) int
tree[maxn<<2],arr[maxn]; int n,h,w,ans; void push_up(int root) { tree[root]=max(tree[root<<1],tree[root<<1|1]); } //void push_down(int root,int L,int R) //{ // if(lazy[root]!=0) // { // int mid=(L+R)>>1; // tree[root<<1]+=lazy[root]*(mid-L+1); // tree[root<<1|1]+=lazy[root]*(R-mid);
// lazy[lson]+=lazy[root]; // lazy[rson]+=lazy[root]; // lazy[root]=0; // } //} void build(int root,int L,int R) { if(L==R) { tree[root]=w; return; } int mid=(L+R)>>1; build(root<<1,L,mid); build(root<<1|1,mid+1,R); push_up(root); } void update(int root,int L,int R,int val) { if(L==R) { ans=L; tree[root]-=val; return; } int mid=(L+R)>>1; if(tree[lson]>=val) update(root<<1,L,mid,val); else update(root<<1|1,mid+1,R,val); push_up(root); } //void update_interval(int root,int L,int R,int LL,int RR,int val) //{ // if(LL<=L && R<=RR) // { // tree[root]+=val*(R-L+1); // lazy[root]+=val; // return; // } // int mid=(L+R)>>1; // if(LL<=mid) update(lson,L,mid,LL,RR,val); // if(RR>mid) update(rson,mid+1,R,LL,RR,val); // push_up(root); //} //int query(int root,int L,int R,int val) //{ // if(L==R) // { // return L; // } // //push_down(root); // int mid=(L+R)>>1; // if(tree[root<<1]>=val) return query(root<<1,L,mid,val); // else if(tree[root<<1|1]>=val) return query(root<<1|1,mid+1,R,val); // else return -1; // //} int main() { while(~scanf("%d%d%d",&h,&w,&n)) { int t=n; h=min(h,n); build(1,1,h); while(t--) { int x; scanf("%d",&x); if(tree[1]<x) { printf("-1\n"); continue; } update(1,1,h,x); printf("%d\n",ans); } } return 0; }