HDU 2795 Billboard

来源:互联网 发布:网络推广专员工作计划 编辑:程序博客网 时间:2024/05/16 05:02

1.题目描述:点击打开链接

2.解题思路:本题可以转化为线段树的单点更新问题。根据题意描述,我们可以维护区间[1,h]上的最大宽度。令结点1是区间[1,h],那么如果tr[1].len<x则说明无解,否则,可以用线段树来更新,每次优先考虑左儿子结点,这样就能保证满足题意了。

3.代码:

#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<bitset>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<complex>#include<functional>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define me(s)  memset(s,0,sizeof(s))#define rep(i,n) for(int i=0;i<(n);i++)typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <ll, ll> P;#define lid (id<<1)#define rid (id<<1|1)const int N=200005;struct Node{    int l,r;    int mx;    int mid(){return l+(r-l)/2;}}tr[N*4];int h,w,n;void build(int L,int R,int id){    tr[id].l=L,tr[id].r=R;    tr[id].mx=w;    if(L==R)return;    int mid=tr[id].mid();    build(L,mid,lid);    build(mid+1,R,rid);}void pushup(int id){    tr[id].mx=max(tr[lid].mx,tr[rid].mx);}int update(int id,int val){    int l=tr[id].l,r=tr[id].r;    if(l==r){tr[id].mx-=val;return l;}//返回所在的行    int p;    if(tr[lid].mx>=val)p=update(lid,val);    else p=update(rid,val);    pushup(id);    return p;}int main(){    while(~scanf("%d%d%d",&h,&w,&n))    {        int x;        build(1,min(200000,h),1);        for(int i=0;i<n;i++)        {            scanf("%d",&x);            if(tr[1].mx<x)puts("-1");            else printf("%d\n",update(1,x));        }    }}

0 0
原创粉丝点击