hdu 2795 Billboard(线段树版)
2014-08-10 21:49
225 查看
题目链接:点击打开链接
题意:一个h*w的板子,往上贴一些1*n的海报,每次选择最上方最左方的地方贴,输出每张海报贴的行数,不能贴就输出-1
实际上就是一个1到h的线段树,每次找到最左边第一个大于n的位置,将这个位置的数减n。
本题h范围是10^9,但因为n的范围是200000,实际上h的范围也是200000,。
线段数保存的是区间最大值,查询时每次都优先看左子树满不满足,这样保证是最靠左的。
代码:
题意:一个h*w的板子,往上贴一些1*n的海报,每次选择最上方最左方的地方贴,输出每张海报贴的行数,不能贴就输出-1
实际上就是一个1到h的线段树,每次找到最左边第一个大于n的位置,将这个位置的数减n。
本题h范围是10^9,但因为n的范围是200000,实际上h的范围也是200000,。
线段数保存的是区间最大值,查询时每次都优先看左子树满不满足,这样保证是最靠左的。
代码:
#include <iostream> #include <cstdio> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; int h,w; int sum[800010]; void pushup(int rt){ sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); } void build(int l,int r,int rt){ if(l==r){ sum[rt]=w; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } int query(int k,int l,int r,int rt){ if(l==r){ sum[rt]-=k; return l; } int m=(l+r)>>1; int res=(sum[rt<<1]>=k?query(k,lson):query(k,rson)); pushup(rt); return res; } int main(){ int n; while(cin>>h>>w>>n){ if(h>n) h=n; build(1,h,1); for(int i=1;i<=n;i++){ int t; scanf("%d",&t); if(sum[1]<t) printf("-1\n"); else printf("%d\n",query(t,1,h,1)); } } return 0; }
相关文章推荐
- hdu-2795-Billboard- 线段树-单点
- hdu 2795 Billboard(线段树)
- HDU - 2795 Billboard 线段树入门
- HDU-2795 Billboard (线段树)RE的教训!
- HDU 2795 Billboard(宣传栏贴公告,线段树应用)
- hdu 2795 Billboard ( 线段树 )
- hdu 2795 Billboard(线段树 求最值的位置)
- HDU 2795 Billboard(线段树)
- hdu 2795 Billboard (线段树)
- 线段树专辑—— hdu 2795 Billboard
- hdu 2795 Billboard线段树运用(单点更新)
- [线段树] HDU 2795 - Billboard
- 线段树练习[单点更新] HDU 2795 Billboard
- HDU 2795 Billboard(线段树)
- HDU 2795 Billboard(线段树)
- HDU2795-Billboard 【线段树】
- HDU 2795 Billboard (线段树,单点查询)
- HDU 2795 Billboard 【线段树】
- HDU 2795 Billboard 贴广告(线段树)
- hdu 2795 Billboard(线段树)