HDU 2795Billboard
题意:(刚开始没看懂题啊 很僵硬 )大概意思就是给你一个n*m的海报 然后 让你贴小广告,优先往上和往右,很明显要建树,这里对于数的叶子节点要分类考虑,首先n与K的关系,n<k时建树的叶子节点应该n,反之为k,存入数的是当前存在的位置最多多少,然后遍历树,若左节点的空位大于要求的调用左儿子,反之右儿子,若不存在直接输出-1即可;
#include<algorithm> #include<iostream> #include<queue> #include<stack> #include<vector> #include<map> #include<set> #include<cstring> #include<cstdio> #define N 200010 #define INF 0x3f3f3f3f using namespace std; typedef struct node{ int x;int y;int date; }node; node a[N*4]; int b[N]; void built(int root,int first,int end,int e){ if(first==end){ a[root].x=first;a[root].y=end;a[root].date=e; return ; } int mid=(first+end)/2; built(root*2,first,mid,e); built(root*2+1,mid+1,end,e); a[root].x=a[root*2].x;a[root].y=a[root*2+1].y;a[root].date=max(a[root*2].date,a[root*2+1].date); } void U(int root,int first,int end,int e,int p){ if(first==end){ if(a[root].date<p){ b[e]=-1; } else{ b[e]=first; a[root].date-=p; } return ; } int mid=(first+end)/2; if(a[root*2].date>=p) U(root*2,first,mid,e,p); else U(root*2+1,mid+1,end,e,p); a[root].date=max(a[root*2+1].date,a[root*2].date); } int main(){ int m,n,k; while(scanf("%d %d %d",&m,&n,&k)==3){ int l; memset(b,0,sizeof(0)); int p; if(m>=k){ p=k; } else{ p=m; } built(1,1,p,n); for(int i=1;i<=k;i++){ scanf("%d",&l); U(1,1,p,i,l); } for(int i=1;i<=k;i++){ printf("%d\n",b[i]); } } return 0; }