今天做了一道看起来不像线段树的题,但是确实是。
题目大致如下:
贴海报,贴的时候往左上角贴,给出区域h*w,而海报的高度默认为1,给出宽度w,问能贴到的最高的位置在哪一行。
思路:
没想到这道题竟然可以用线段树解决。
要找到最靠上的海报只需要查询一次线段树就好了,从根节点往下走,如果左子树的可用的最大长度满足就往左走,否则往右走。
附上代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef struct
{
int l,r,val;
}Tree;
Tree tree[1000000];
int m;
void Build(int t,int l,int r)
{
tree[t].l=l;
tree[t].r=r;
tree[t].val=m;
if (l==r) return;
int mid=(l+r)/2;
Build(2*t+1,l,mid);
Build(2*t+2,mid+1,r);
}
int max(int a,int b)
{
if(a<b)
a=b;
return a;
}
int min(int a,int b)
{
if(a>b)
a=b;
return a;
}
void Find(int t,int val)
{
if (tree[t].l==tree[t].r)
{
tree[t].val-=val;
printf("%d\n",tree[t].l+1);
return;
}
if (tree[2*t+1].val>=val) Find(2*t+1,val);
else Find(2*t+2,val);
tree[t].val=max(tree[2*t+1].val,tree[2*t+2].val);
}
int main()
{
int i,j,n,x,T;
while(scanf("%d%d%d",&n,&m,&T)!=EOF)
{
n=min(n,200000);
Build(0,0,n-1);
while(T--)
{
scanf("%d",&x);
if (x>tree[0].val) printf("-1\n");
else Find(0,x);
}
}
return 0;
}
3 5 5 2 4 3 3 3
1 2 1 3 -1