hdu2795Billboard

来源:互联网 发布:仿淘宝购物车的htmlcss 编辑:程序博客网 时间:2024/04/29 20:59

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

题意:给定一个高为h宽为w的公告栏,然后给出n张要粘贴的高为1宽为wi的公告。每张公告都会选择能贴的最高行的靠左边贴。能贴输出行不能贴输出-1。

分析:因为最多才200000张公告,我们可以以行为基础建线段树,每次找最左边的剩余宽度还大于等于wi的位置。O(nlog(min(h,n)))。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=200010;const int MAX=1000000100;const int mod=100000000;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=998244353;const ll INF=10000000010;typedef double db;typedef unsigned long long ull;int n,h,w,mx[4*N];void build(int x,int l,int r) {    mx[x]=w;    if (l==r) return ;    int mid=(l+r)>>1;    build(2*x,l,mid);build(2*x+1,mid+1,r);}int query(int x,int l,int r,int w) {    if (l==r) return l;    int mid=(l+r)>>1;    if (mx[2*x]>=w) return query(2*x,l,mid,w);    else return query(2*x+1,mid+1,r,w);}void updata(int x,int l,int r,int w) {    if (l==r) { mx[x]-=w;return ; }    int mid=(l+r)>>1;    if (mx[2*x]>=w) updata(2*x,l,mid,w);    else updata(2*x+1,mid+1,r,w);    mx[x]=max(mx[2*x],mx[2*x+1]);}int main(){    int i,d,x;    while (scanf("%d%d%d", &h, &w, &n)!=EOF) {        d=min(h,n);build(1,1,d);        for (i=1;i<=n;i++) {            scanf("%d", &x);            if (mx[1]<x) printf("-1\n");            else {                printf("%d\n", query(1,1,d,x));                updata(1,1,d,x);            }        }    }    return 0;}


0 0
原创粉丝点击