首页 > 其他分享 >hdu 2795(线段树)

hdu 2795(线段树)

时间:2023-05-29 19:35:08浏览次数:35  
标签:hdu return int 线段 tree value id 2795


解题思路:这道题很难想到是用线段树,确实转化的很巧妙


实际上,我们只需要利用线段树(记录1-h)维护哪个位置的剩余空间最大即可,即1,2,......,h是线段树的叶子节点,我们每次要找的就是叶子节点的剩余空间的最大值,只要能够想到这里就很容易啦。。另外如果h>n的话,就令h=n,否则就是类似于位置多而要贴上去的砖少,这样就不合题目意思了。。



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 200005;
struct seg
{
	int l,r,value,id;
}tree[maxn<<2];
int h,w,n;

void build(int l,int r,int u)
{
	tree[u].l = l;
	tree[u].r = r;
	tree[u].value = w;
	tree[u].id = l;
	if(l == r) return;
	int mid = (l + r) >> 1;
	build(l,mid,2*u);
	build(mid+1,r,2*u+1);
}

void update(int l,int r,int v,int u)
{
	if(tree[u].l >= l && tree[u].r <= r){
		tree[u].value -= v;
		return;
	}
	int mid = (tree[u].l + tree[u].r) >> 1;
	if(l <= mid) update(l,r,v,2*u);
	if(r > mid) update(l,r,v,2*u+1);
	if(tree[2*u].value >= tree[2*u+1].value){
		tree[u].value = tree[2*u].value;
		tree[u].id = tree[2*u].id;
	}
	else{
		tree[u].value = tree[2*u+1].value;
		tree[u].id = tree[2*u+1].id;
	}
}

int query(int v,int u)
{
	if(tree[u].value < v) return -1;
	if(tree[u].l == tree[u].r) return tree[u].id;
	if(tree[2*u].value >= v) 
		return query(v,2*u);
	else return query(v,2*u+1);
}

int main()
{
	int x;
	while(scanf("%d%d%d",&h,&w,&n)!=EOF)
	{
		if(h > n) h = n;
		build(1,h,1);
		for(int i = 1; i <= n; i++){
			scanf("%d",&x);
			int tmp = query(x,1);
			if(tmp != -1){
				printf("%d\n",tmp);
				update(tmp,tmp,x,1);
			}
			else printf("-1\n");
		}
	}
	return 0;
}



标签:hdu,return,int,线段,tree,value,id,2795
From: https://blog.51cto.com/u_16143128/6373662

相关文章

  • hdu 1698(线段树区间更新)
    解题思路:线段树区间更新水题。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintmaxn=100005;structseg{ intl,r,sum,lazy;}tree[maxn<<2];voidbuild(intl,intr,intu){ tree[u].l=l; tree[u].r=r; t......
  • hdu 1511(dp)
    解题思路:两次dp确实很巧妙,我只想到了一次dp算出最后那个数最小,其实题目要求还要保证第一个数尽可能大,一开始也没有注意到。。AC:#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#include<math.h>#include<stdlib.h>#include<time.h>usingnamesp......
  • hdu 5102(队列+节点扩展)
    TheK-thDistanceTimeLimit:8000/4000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionGivenatree,whichhasnnodeintotal.Definethedistancebetweentwonodeuandvisthenumberofedgeontheirunique......
  • hdu 5367(线段树+区间合并)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5367官方题解:对于求“高山脉”长度,可以利用线段树。树节点中保存左高度连续长度,左高度连续区间的高度,左高度连续区间的状态(即是否高于第一个高度不同的山),右高度连续长度,右高度连续区间的高度,右高度连续区间的状态,每段区间内的“......
  • hdu 5201(隔板法+容斥原理)
    TheMonkeyKingTimeLimit:8000/4000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionnpeaches.Andtherearemmonkeys(includingGoKu),theyarenumberedfrom1tom,GoKu’snumberis1.GoKuwa......
  • hdu 5086(dp)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5086题目大意:给出长度为n的数组,然后要求累计里面的每个子串的和。解题思路:这道题直接枚举肯定不行,所以要找递推关系。假设:{1,2,3,4}为某一个序列,假设我们已经找到了{1,2,3},接下来把{4}加入进去;由于{1,2,3}已经有{1},{2},{3},{1,......
  • hdu 5188(限制01背包)
    zhxandcontestTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionAsoneofthemostpowerfulbrushesintheworld,zhxusuallytakespartinallkindsofcontests.Oneday,zhxtakespar......
  • hdu 5171(矩阵快速幂)
    GTY'sbirthdaygiftTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptiona,b∈S),andadda+b Input2≤n≤100000,1≤k≤1000000000).Thesecondlinecontainsnelementsai......
  • hdu 5157(manacher+前缀和+树状数组)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5157解题思路:我们可以先用mancher算法对字符串进行处理,把以每个点为中心的回文串半径求出来,然后进行处理。加入对以p为中心的点,从p-r[i]+1~p都是回文串的开头,那么对于每个回文串(开头是j)只要记录结尾从1~j-1的回文串个数,我们可......
  • hdu:第K小的数(构造二分)
    ProblemDescription给定\(n\)个正整数\(a_1,a_2,\dots,a_n\)和\(m\)个正整数\(b_1,b_2,\dots,b_m\)。请在\(n\timesm\)个\(a_i+b_j(1\leqi\leqn,1\leqj\leqm)\)中,找到第\(k\)小的数(不去重)。Input第一行包含一个正整数\(T(1\leqT\leq10)\),表示测试数据的组数。每组......