题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795

题意:有一个 h * w 的板子,要在上面贴 n 条 1 * x 的广告,在贴第 i 条广告时要尽量将其靠上贴,并输出其最上能贴在哪个位置;

思路:可以将每行剩余空间大小存储到一个数组中,那么对于当前 1 * x 的广告,只需找到所有剩余空间大于的 x 的行中位置最小的即可;

不过本题数据量为 2e5,直接暴力因该会 tle.可以用个线段树维护一下区间最大值,然后查询时对线段树二分即可;

代码:

 #include <iostream>
#include <stdio.h>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const int MAXN = 2e5 + ;
int Max[MAXN << ], h, w, n; int max(int a, int b){
return a > b ? a : b;
} void push_up(int rt){
Max[rt] = max(Max[rt << ], Max[rt << | ]);
} void build(int l, int r, int rt){//建树
Max[rt] = w;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} void update(int p, int x, int l, int r, int rt){//单点更新
if(l == r){
Max[rt] -= x;
return;
}
int mid = (l + r) >> ;
if(p <= mid) update(p, x, lson);
else update(p, x, rson);
push_up(rt);
} int query(int x, int l, int r, int rt){//查询
if(l == r) return l;
int mid = (l + r) >> ;
int ans = ;
if(Max[rt << ] >= x) ans = query(x, lson);
else ans = query(x, rson);
return ans;
} int main(void){
while(~scanf("%d%d%d", &h, &w, &n)){
if(h > n) h = n;
build(, h, );
while(n--){
int x, cnt;
scanf("%d", &x);
if(Max[] < x){
printf("-1\n");
continue;
}else printf("%d\n", cnt = query(x, , h, ));
update(cnt, x, , h, );
}
}
return ;
}

其实这个代码中的更新的路径和查询的路径是一样的,可以优化一下,将更新写进查询里面去;

优化代码:

 #include <iostream>
#include <stdio.h>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const int MAXN = 2e5 + ;
int Max[MAXN << ], h, w, n; int push_up(int rt){
Max[rt] = max(Max[rt << ], Max[rt << | ]);
} void build(int l, int r, int rt){
Max[rt] = w;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} int query(int x, int l, int r, int rt){
if(l == r){
Max[rt] -= x;
return l;
}
int mid = (l + r) >> ;
int cnt = (Max[rt << ] >= x) ? query(x, lson) : query(x, rson);
push_up(rt);
return cnt;
} int main(void){
while(~scanf("%d%d%d", &h, &w, &n)){
if(h > n) h = n;
build(, h, );
while(n--){
int x;
scanf("%d", &x);
if(Max[] < x) printf("-1\n");
else printf("%d\n", query(x, , h, ));
}
}
return ;
}

hdu2795(线段树单点更新&区间最值)的更多相关文章

  1. 【HDU】1754 I hate it ——线段树 单点更新 区间最值

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. hdu 1754 I Hate It 线段树 单点更新 区间最值

    线段树功能:update:单点更新 query:区间最值 #include <bits/stdc++.h> #define lson l, m, rt<<1 #define r ...

  3. HDU 1754 I Hate It(线段树单点更新区间最值查询)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. hihoCoder #1586 : Minimum-结构体版线段树(单点更新+区间最值求区间两数最小乘积) (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1586 : Minimum Time Limit:1000ms Case Time Limit:1000ms Memory Limit:256MB Description You are give ...

  5. HDU 1754 I Hate It(线段树单点替换+区间最值)

    I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...

  6. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  7. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  8. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  9. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. 顽石系列:Java技术面试

    顽石系列:Java技术面试 JDBC相关 1.Statement与PreparedStatement的区 别,什什么是SQL注⼊入,如何防⽌止SQL注⼊? PreparedStatement支持动态设 ...

  2. ansible3

    一.setup模块 ansible的setup模块主要用来收集信息,查看参数: [root@localhost ~]# ansible-doc -s setup # 查看参数,部分参数如下: filt ...

  3. Python网络编程--Echo服务

    Python网络编程--Echo服务 学习网络编程必须要练习的三个小项目就是Echo服务,Chat服务和Proxy服务.在接下来的几篇文章会详细介绍. 今天就来介绍Echo服务,Echo服务是最基本的 ...

  4. matlab之flipud()函数

    此函数实现矩阵的上下翻转.fliplw()实现左右旋转. 举例: a =[1 2;3 4;5 6] flipud(a)的结果: 5 6 3 4 1 2 fliplr(a)的结果: 2 1 4 3 6 ...

  5. Bootstrap简单介绍

    一.一个小知识点 1.截取长屏的操作 2.设置默认格式 3.md,sm, xs 4.空格和没有空格的选择器 二.响应式介绍 - 响应式布局是什么? 同一个网页在不同的终端上呈现不同的布局等 - 响应式 ...

  6. 破解 Navicat Premium 12

    一.下载 若文件百度云链接失效,请发邮件给博主:1766211120@qq.com 1.安装文件下载 v12.0.11(x64)版本下载地址如下 链接:https://pan.baidu.com/s/ ...

  7. Oracle学习笔记_05_ 一个创建表空间、创建用户、授权的完整过程

    一.完整命令 su - oracle sqlplus /nolog conn /as sysdba create tablespace scaninvoice logging datafile '/u ...

  8. Unix环境编程之文件IO

    1.文件IO 2.文件与目录 3.进程 4.多线程编程 5.信号 6.进程间通信 学习linux编程,首先要学会使用shell,这里一些基础命令就不介绍了.这里唯一要提的一个shell命令就是man. ...

  9. redis cluster 实践总结

      最近项目接触到了redis cluster,现在趁着使用做一下总结,记录一下遇到过的问题,简单的概述一下常用到的命令和功能. 本篇文章主要是以运维的角度去讲述如何去更好的规划redis clust ...

  10. 损失函数(Loss function) 和 代价函数(Cost function)

    1损失函数和代价函数的区别: 损失函数(Loss function):指单个训练样本进行预测的结果与实际结果的误差. 代价函数(Cost function):整个训练集,所有样本误差总和(所有损失函数 ...