HDU:2795 Billboard
来源:互联网 发布:hadoop书籍推荐 知乎 编辑:程序博客网 时间:2024/06/02 11:30
再次领教了线段树的威力。维护一个最大值,优先选择左边的,更新操作写在了查询里面。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>#define ll long long#define INF 2139062143#define MAXN 105using namespace std;const int MAX_N= 1<<19;int mxn,n,h,w;int dat[MAX_N];void build(int k,int l,int r){ dat[k]=w; if(l==r) return; build(2*k,l,(l+r)/2); build(2*k+1,(l+r)/2+1,r);}void Init(){ mxn=1; while(mxn<h) mxn*=2; memset(dat,0,sizeof(dat)); build(1,1,h);}int query(int x,int k,int l,int r){ if(l==r) { dat[k]-=x; return l; } else { int ans=0; if(dat[2*k]>=x) ans=query(x,2*k,l,(l+r)/2); else ans=query(x,2*k+1,(l+r)/2+1,r); dat[k]=max(dat[2*k],dat[2*k+1]); return ans; }}int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF) { h=min(h,n); Init(); int t; for(int i=0;i<n;++i) { scanf("%d",&t); if(dat[1]<t) printf("-1\n"); else printf("%d\n",query(t,1,1,h)); } } return 0;}
后来重写了一遍。
首先h=min(h,200000),以h为结点建立线段树,树上存某个区间内宽度的最大值。这样每次查询相当于二分寻找大于t的叶结点,优先从左寻找。找到的叶结点同时要减去t,然后更新父亲结点。不存在时返回-1。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <set>#include <map>#include <algorithm>#define ll long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN 500005#define LEN 222222<<2using namespace std;int h,w,n;struct Segment_tree{private: int data[LEN],sz; void pushup(int o) { data[o]=max(data[o<<1],data[o<<1|1]); } int myquery(int o,int L,int R,int v) { if(L==R) { data[o]-=v; return L; } int M=(L+R)/2; int res=-1; if(v<=data[o<<1]) res=myquery(o<<1,L,M,v); else if(v<=data[o<<1|1])res= myquery(o<<1|1,M+1,R,v); pushup(o); return res; }public: void clear() { sz=h; } void build(int o,int L,int R) { if(L==R) data[o]=w; else { int M=(L+R)/2; build(o<<1,L,M); build(o<<1|1,M+1,R); data[o]=w; } } int query(int p) { return myquery(1,1,sz,p); }};Segment_tree tree;int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF) { int t; h=min(h,200000); tree.clear(); tree.build(1,1,h); for(int i=0; i<n; ++i) { scanf("%d",&t); printf("%d\n",tree.query(t)); } } return 0;}
0 0
- 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
- HDU 2795 Billboard
- hdu 2795 Billboard
- Hdu 2795 Billboard
- Hdu 2795 Billboard
- hdu 2795 Billboard
- hdu 2795 Billboard
- hdu 2795 Billboard
- 【设计模式-代理模式】
- 写给即将进入IT行业的应届生们——谈谈IT岗位(只转载软件工程师的部分&美化了一下)
- 九度OJ 1078 二叉树遍历
- 动手学MFC之二——对话框初探
- duilib 关于怎么调用ListUI中的GetItemText
- HDU:2795 Billboard
- ubuntu12.04英文版安装中文输入法
- Understanding a Kernel Oops
- Meclispse 相关配置
- linux使用samba共享文件夹
- Google java 编程规范
- Perl笔记:Perl语言入门(第六版) - 切片、捕获错误
- 深入淺出中国剩余定理【轉】
- 辞典