[USACO12MAR]花盆Flowerpot 二分答案+单调队列

题意:

给出N滴水的坐标,y表示水滴的高度,x表示它下落到x轴的位置。

每滴水以每秒1个单位长度的速度下落。你需要把花盆放在x轴上的某个位置,使得从被花盆接着的第1滴水开始,到被花盆接着的最后1滴水结束,之间的时间差至少为D。

我们认为,只要水滴落到x轴上,与花盆的边沿对齐,就认为被接住。给出N滴水的坐标和D的大小,请算出最小的花盆的宽度W。

 

数据范围:

40%的数据:1 ≤ N ≤ 1000,1 ≤ D ≤ 2000;

100%的数据:1 ≤ N ≤ 100000,1 ≤ D ≤ 1000000,0≤x,y≤10^6。

--------------------------------------------------我是分割线----------------------------------------------------

题解:对于40%的数据,二分花盆的宽度,朴素O(N^2)检验宽度len能否满足条件,总时间复杂度O(N^2logN),期望得分40,实际得分50。

#include<bits/stdc++.h>#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a); i <= (b); i++) 
#define per(i, a, b) for(int i = (a); i >= (b); i--)using namespace std;typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
struct node{ int x, y; } a[N];
int n, d, l = 1, r, ans = -1;
inline int read(){int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar();}while(ch >='0' && ch <='9') { x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}return x*f;
}
bool mycmp(node a, node b){ return a.x < b.x; }
void init(){n = read(); d = read();rep(i, 1, n) a[i].x = read(), a[i].y = read(), r = max(r, a[i].x);sort(a+1, a+n+1, mycmp);
}
bool check(int len){int dist = 0;rep(i, 1, n){int t = a[i].y, maxx = 0;maxx = max(maxx, a[i].y);rep(j, i+1, n){if(i == j) continue;if(a[j].x >= a[i].x && a[j].x <= a[i].x + len) {maxx = max(maxx, a[j].y);t = min(t, a[i].y);}}dist = max(dist, abs(maxx - t)); if(dist >= d) return true;}return false;
}
void work(){while(l < r){int mid = (l+r) >> 1;if(check(mid)) r = mid, ans = mid;else l = mid + 1;}printf("%d\n", ans);
}
int main(){init();work();return 0;
}
View Code

考虑对朴素算法进行优化,我们发现,检验的过程max-min的值我们可以预处理维护的,于是把整条x轴看成一个区间,每个水滴的y值看成是区间下标的权值,于是我们就不难想到ST表,运用ST表预处理区间的最大值和最小值,于是可以O(N)检验。总时间复杂度O(NlogN),常数略大。

#include<bits/stdc++.h>#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a); i <= (b); i++) 
#define per(i, a, b) for(int i = (a); i >= (b); i--)using namespace std;typedef pair<int, int> pii;
typedef double db;
const int N = 1e5 + 50;
struct node{ int x, y; } a[N];
int n, d, l = 1, r, ans = -1, maxn;
int Max[N*10][21], Min[N*10][21];
inline int read(){int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar();}while(ch >='0' && ch <='9') { x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}return x*f;
}
int ask_max(int l, int r){int k = log2(r-l+1);return max(Max[l][k], Max[r - (1<<k) + 1][k]);
}
int ask_min(int l, int r){int k = log2(r-l+1);return min(Min[l][k], Min[r - (1<<k) + 1][k]);
}
void init(){memset(Min, 0x3f, sizeof(Min));n = read(); d = read();rep(i, 1, n){a[i].x = read(), a[i].y = read(), maxn = max(maxn, a[i].x);Max[a[i].x][0] = max(Max[a[i].x][0], a[i].y);Min[a[i].x][0] = min(Min[a[i].x][0], a[i].y);}int t = log2(maxn);rep(j, 1, t) rep(i, 1, maxn - (1<<j) + 1) {Max[i][j] = max(Max[i][j-1], Max[i + (1<<(j-1))][j-1]);  Min[i][j] = min(Min[i][j-1], Min[i + (1<<(j-1))][j-1]);}
}
bool check(int len){rep(i, 1, maxn-len){if(ask_max(i, i+len) - ask_min(i, i+len) >= d) return true;}return false;
}
void work(){r = maxn;while(l <= r){int mid = (l+r) >> 1;if(check(mid)) r = mid-1, ans = mid;else l = mid + 1;}printf("%d\n", ans);
}
int main(){init();work();return 0;
}
View Code

这里再介绍一种新的维护方法,即动态维护区间最大值和最小值的基本套路。

当我们二分到一个长度时,对于这个长度所能产生的最大的贡献即为max{max[i,i+len] - min[i,i+len] }。

这时,我们就可以使用单调队列。

维护两个单调队列,分别是单调不降和单调不升的队列,两个队头{min,max}即为所需求的答案。

至于怎么维护,维护单调队列的基本形式,如果队头没有下一个元素优,那么就弹出队头,直到符合单调性为止,然后对队尾操作,使得队列包含的区间长度等于len+1。

总时间复杂度O(NlogN),常数较小。

#include<bits/stdc++.h>#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)using namespace std;typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
struct node{ int x, y; } a[N];
int n, d, maxx, ans = -1, b[N], k[N];
struct npp{ int z, id; } ql[N], qh[N];
inline int read(){int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar();}while(ch >='0' && ch <='9') { x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}return x*f;
}
void init(){memset(k, 0x3f, sizeof(k));n = read(); d = read();rep(i, 1, n) a[i].x = read(), a[i].y = read(), maxx = max(maxx, a[i].x);rep(i, 1, n) b[a[i].x] = max(b[a[i].x], a[i].y); rep(i, 1, n) k[a[i].x] = min(k[a[i].x], a[i].y);
}
bool check(int len){len++;int ls = 1, rs = 0, lh = 1, rh = 0, sum = 0;rep(i, 1, maxx) {while(ls <= rs && k[i] <= ql[rs].z) rs--;while(lh <= rh && b[i] >= qh[rh].z) rh--;while(ql[ls].id <= i-len) ls++;while(qh[lh].id <= i-len) lh++;ql[++rs].z = k[i], ql[rs].id = i;qh[++rh].z = b[i], qh[rh].id = i;if(i >= len) sum = max(sum, qh[lh].z - ql[ls].z);if(sum >= d) return true;} return false;
}
void work(){int l = 1, r = maxx;while(l <= r){int mid = (l+r) >> 1;if(check(mid)) r = mid-1, ans = mid;else l = mid+1;}printf("%d\n", ans);
}
int main(){init();work();return 0;
}
View Code

 其实除了单调队列以外,动态维护区间最值还可以用STL的<set>,或者堆,不过时间复杂度要多一个log,可能会被卡常,推荐使用单调队列。

转载于:https://www.cnblogs.com/smilke/p/11572809.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jQuery使用手册

jQuery是一款同prototype一样优秀js开发库类&#xff0c;特别是对css和XPath的支持&#xff0c;使我们写js变得更加方便&#xff01;如果你不是个js高手又想写出优 秀的js效果&#xff0c;jQuery可以帮你达到目的&#xff01;下载地址&#xff1a;Starterkit &#xff08;http:…

全志_外部中断

全志_外部中断 平台&#xff1a;全志A64 源码&#xff1a;Android 7.1  Linux3.1 1 #include <linux/init.h>2 #include <linux/module.h>3 #include <linux/fs.h>4 #include <linux/device.h>5 #include <linux/slab.h>6 #include <linux/…

[ZJOI2007]时态同步 树形DP

题意&#xff1a;给定一棵N个节点的无根树&#xff0c;每条边都有一个权值V&#xff0c;选取其中一个点作为关键点&#xff0c;你可以任意增加某条边的权值&#xff0c;求使得从关键点出发&#xff0c;到任意一个叶子节点的距离都相同所需要增加的权值和。 数据范围&#xff1a…

题解P3942_将军令

初始数组忘了赋初值&#xff0c;&#xff0c;&#xff0c;我真是个机灵鬼 还有这题是三倍经验P2279&&P2016&#xff0c;这题的实现思想来自P2279首个题解 luogu 简化题意 给你一棵树&#xff0c;你有一些可以覆盖范围为$k$的障碍物&#xff0c;问最少放几个障碍物可以使…

[SCOI2009]生日礼物 单调性尺取法

题意&#xff1a;给你n个k种颜色的点&#xff0c;每个点都有坐标和颜色两个属性&#xff0c;选出一个长度尽量短的区间&#xff0c;使得每种颜色的点都在区间内出现。 数据范围&#xff1a; 对于50%的数据&#xff0c; N≤10000&#xff1b; 对于80%的数据&#xff0c; N≤8000…

PJ2018T4 对称二叉树 树形结构

题意&#xff1a;现在给出一棵二叉树&#xff0c;希望你找出它的一棵子树&#xff0c;该子树为对称二叉树&#xff0c;且节点数最多。请输出这棵子树的节点数。对称二叉树满足&#xff1a;将这棵树所有节点的左右子树交换后&#xff0c;新树和原树对应位置的结构相同且点权相等…

提高ASP.Net应用程序性能的十大方法

一、返回多个数据集 检查你的访问数据库的代码&#xff0c;看是否存在着要返回多次的请求。每次往返降低了你的应用程序的每秒能够响应请求的次数。通过在单个数据库请求中返回多个结果集&#xff0c;可以减少与数据库通信的时间&#xff0c;使你的系统具有扩展性&#xff0c;…

【NOIP2015提高组】子串 区间DP+滚动数组优化

题意&#xff1a; 有两个仅包含小写英文字母的字符串 A 和 B。 现在要从字符串 A 中取出 k 个互不重叠的非空子串&#xff0c;然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串。 请问有多少种方案可以使得这个新串与字符串 B 相等&#xff1f; …

教你如何去淘便宜机票

机票四月二十日集体变相涨价后&#xff0c;中央电视台曾经报道&#xff0c;今后没有5折以下机票&#xff0c;今后也不再叫多少折&#xff0c;而是直接报价&#xff0c;但是春秋航空不再此之列&#xff0c;原因是这次变相提价是一个叫中航信公司在操作&#xff0c;他们不代理春秋…

32位单精度浮点乘法器的FPGA实现

摘 要: 采用Verilog HDL语言, 在FPGA上实现了32位单精度浮点乘法器的设计, 通过采用改进型Booth编码&#xff0c;和Wallace 树结构, 提高了乘法器的速度。本文使用Altera Quartus II 4.1仿真软件, 采用的器件是EPF10K100EQ 240 -1, 对乘法器进行了波形仿真, 并采用0.5CMOS工艺…

我们的运动会

不久前&#xff0c;我们举办了微软中国研发集团的首届运动会。遗憾的是&#xff0c;当时我自己由于公务在身没能参加。事后同事们把许多精彩的图片与我分享&#xff0c;让我十分羡慕他们有机会大显身手&#xff0c;现在贴出来让大家看看他们的飒爽英姿&#xff0c;一睹为快。运…

性能测试工具SilkPerformer介绍

SilkPerformer 是业界最强大&#xff0c;且最易用的企业级负载和强度测试解决方案&#xff0c;用于对关键任务应用的质量进行优化。SilkPerformer使用可视化脚本生成技术和对存在成千上万的并发用户的多个应用环境进行测试的能力&#xff0c;使您能够在企业应用部署之前&#x…

Office2010试用

昨天看到了Office的下载地址&#xff0c;就安装了一个试了试&#xff0c;总体感觉和Office2007变化不大&#xff0c;外观配色上看起来非常舒服&#xff0c;Aero效果用得更多了&#xff0c;具体功能改进还没有细研究&#xff08;其实一直感觉到了2003后的更新大都只是在界面和适…

配置WINDOWS群集

配置WINDOWS群集 实验说明&#xff1a;本实验用于配置WINDOWS群集 实验名称&#xff1a;配置WINDOWS群集 实验目的&#xff1a;理解WINDOWS群集服务的工作原理&#xff0c;熟练掌握安装WINDOWS群集服务及配置WINDOWS群集 实验设备&#xff1a;windows server 2003 VM 二台 实验…

李天平×××作诞生记——《亮剑.NET:.NET深入体验与实战精要》

从开始搞.NET开发至今已经有六、七年了&#xff0c;从当初对.NET一无所知&#xff0c;到现在领导研发团队进行各种项目的开发和架构设计&#xff0c;几年里经历了各种沟沟坎坎&#xff0c;无论是技术上的&#xff0c;还是管理上的。这些经历和经验就像一笔财富&#xff0c;为自…

计组学习笔记(一):浮点数的表示和运算

最近学习计算机组成原理&#xff0c;遇到许多疑难问题&#xff0c;接下来写一写我在学习浮点数方面知识的理解&#xff0c;在巩固的同时也方便日后的复习。一、浮点数的表示1、浮点数的表示格式浮点数&#xff0c;顾名思义&#xff0c;就是小数点不固定的数。计算机中&#xff…

如何查看linux的版本

虽然用过些版本的LINUX系统&#xff0c;但是没有查看过具体的版本是多少来着&#xff0c;下午心血来潮&#xff0c;想查看下自己的版本&#xff0c;到网上收索了下&#xff0c;看到有一大堆命令出来&#xff0c;呵呵&#xff0c;1 最简单的一个uname -a2 cat /etc/issue …

JDBC批量Insert深度优化(有事务)

JDBC批量Insert深度优化&#xff08;有事务&#xff09;环境&#xff1a;MySQL 5.1RedHat Linux AS 5JavaSE 1.5DbConnectionBroker 微型数据库连接池测试的方案&#xff1a;执行10万次Insert语句&#xff0c;使用不同方式。A组&#xff1a;静态SQL&#xff0c;自动提交&#x…

ActiveBpel部署运行BPEL流程实例

本文接收使用ActiveBpel开发&#xff0c;部署和运行BPEL流程实例。本文的例子工程和服务工程请见附件。1. 安装ActiveBpel5.0.2要安装ActiveBpel5.0.2&#xff0c;需要先安装JDK1.5&#xff0c;Tomcat。注意这里是JDK1.5版本的&#xff0c;ActiveBpel5.0.2不支持JDK1.5以上的版…

活动目录实战系列五(更改域名)

在单域环境下且没有什么服务的情况的改域名还行&#xff0c;如果网络环境比较复杂或者有其他服务&#xff0c;不建议更改。以免发生错误。在实验中由于虚拟机坏掉在这里使用了两个&#xff0c;有部分图片对不上&#xff0c;请谅解。 WIN2000域不支持域重命名域重命名并不是在域…