ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)
ZOJ 3597
题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你被允许选择一个连续的Q个靶子,使得这P把枪所打到的靶子的数目最多,问打到的靶子数目的期望值是多少。
这题通过简单的转化就可以转换成为另一个模型:
如果第a把枪可以打到第b个靶子,那么将其视为二位平面上的一个点(b, a), 问题转化为一个Q * P的矩形最多可以覆盖多少个点。只是有一点需要注意的就是同一把枪只能打到一个靶子,所以在a相等的情况下最多只能覆盖一个b。
至于如何求矩形覆盖点的个数,我这也是第一次写,所以查阅了有关资料。
方法是将矩形的右界作为参考点,找出参考点在哪一个区间(线段)内矩形都可以覆盖到这个点,这样每一个点就对应y相等的一段线段,原题就转化成为了高度y小于P的区间内某一个位置x上的覆盖次数的最大值,可以用线段树的离线操作(扫描线)来完成。
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, (L + R)>>1 18 #define rson k<<1|1, ((L + R)>>1) + 1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 51000; 36 const int MAXM = 110000; 37 const double eps = 1e-4; 38 //LL MOD = 987654321; 39 40 #define OK(i) (i > 0 && p[i - 1].y == p[i].y && p[i].x <= p[i - 1].x + Q - 1) 41 42 int T, N, M, P, Q, K; 43 struct Point { 44 int x, y; 45 bool operator < (const Point &A) const { 46 return y == A.y ? x < A.x : y < A.y; 47 } 48 }p[MAXM]; 49 50 struct SegTree { 51 LL ma[MAXN<<2], add[MAXN<<2]; 52 53 void build(int k, int L, int R) { 54 ma[k] = add[k] = 0; 55 if(L == R) return ; 56 build(lson); build(rson); 57 } 58 59 void pushDown(int k) { 60 ma[k<<1] += add[k]; add[k<<1] += add[k]; 61 ma[k<<1|1] += add[k]; add[k<<1|1] += add[k]; 62 add[k] = 0; 63 } 64 65 void update(int k, int L, int R, int l, int r, int val) { 66 if(R < l || L > r) return ; 67 if(l <= L && R <= r) { ma[k] += val; add[k] += val; return ; } 68 pushDown(k); 69 update(lson, l, r, val); 70 update(rson, l, r, val); 71 ma[k] = max(ma[k<<1], ma[k<<1|1]); 72 } 73 74 LL query(int k, int L, int R, int l, int r) { 75 if(R < l || L > r) return 0; 76 if(l <= L && R <= r) return ma[k]; 77 pushDown(k); 78 return max(query(lson, l, r), query(rson, l, r)); 79 } 80 81 }segTree; 82 83 int main() 84 { 85 //FIN; 86 while(~scanf("%d", &T)) while(T--) 87 { 88 scanf("%d %d %d %d %d", &N, &M, &P, &Q, &K); 89 rep (i, 0, K - 1) scanf("%d %d", &p[i].y, &p[i].x); 90 sort(p, p + K); 91 92 segTree.build(1, 1, M); 93 LL ans = 0, fr = 0, re = 0; 94 rep (i, P, N) { 95 while(fr < K && p[fr].y <= i) { 96 int st = OK(fr) ? p[fr-1].x + Q : p[fr].x; 97 int ed = min(p[fr].x + Q - 1, M); 98 segTree.update(1, 1, M, st, ed, 1); 99 fr ++; 100 } 101 while(i - p[re].y >= P) { 102 int st = OK(re) ? p[re-1].x + Q : p[re].x; 103 int ed = min(p[re].x + Q - 1, M); 104 segTree.update(1, 1, M, st, ed, -1); 105 re ++; 106 } 107 ans += segTree.query(1, 1, M, 1, M); 108 } 109 printf("%.2lf\n", (double)ans / (N - P + 1)); 110 } 111 return 0; 112 }
转载于:https://www.cnblogs.com/gj-Acit/p/4493091.html
ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)相关推荐
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- 线段树扫描线求矩形周长详解
线段树扫描线求矩形周长详解 原创 wucstdio 最后发布于2018-04-24 16:12:09 阅读数 841 收藏 发布于2018-04-24 16:12:09 版权声明:本文为博主原创文章, ...
- hdu3255 线段树扫描线求体积
题意: 给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值. 思路: 线段树扫描线 ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- hdu 1542 Atlantis (线段树+扫描线)
http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...
- bzoj 1645: [Usaco2007 Open]City Horizon 城市地平线(线段树扫描线)
1645: [Usaco2007 Open]City Horizon 城市地平线 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 732 Solved: ...
- 亚特兰蒂斯【线段树+扫描线+离散化】
亚特兰蒂斯[线段树+扫描线+离散化] POJ1151.ACwing247 题目: 有几个古希腊书籍中包含了对传说中的亚特兰蒂斯岛的描述. 其中一些甚至包括岛屿部分地图. 但不幸的是,这些地图描述了亚特 ...
- 2016 UESTC Training for Data Structures F - 郭大侠与“有何贵干?” CDOJ 1335 线段树 扫描线 离散化
F - 郭大侠与"有何贵干?" 就是给一个三维空间,和N个长方体,问覆盖K次的体积 x和y都是1e9,但是z是[1,3],所以可以把这个分为两个二维平面,求被覆盖K次的面积,最后加 ...
最新文章
- Android开发--BroadcastReceiver2
- spring零碎知识点(二)
- Apache优化——日志管理
- 使用JavaSymbolSolver解决Java代码中的方法调用
- vscode浏览器扩展(图文教程) - 设置篇
- CMU 15-213 Introduction to Computer Systems学习笔记(16) Virtual Memory: Concepts
- VS注册登录不显示界面内容
- 生物信息学中用到的计算机知识,生物信息学期末复习知识点总结
- 免费试用微软云服务Azure(无需信用卡版)
- 人生的镜像-菌群人生,从出生到死亡的菌群演替
- Python实战——外星人入侵游戏
- 如何查看2020最新版谷歌地球高精度卫星地图(附下载方法)
- 鲁迅研究(海南大学)
- 最新搜狗泛目录程序,搜狗站群泛目录,搜狗蜘蛛蜘蛛池(图文)
- Web安全 学习笔记
- PCL点云处理之平面内两直线求交点(五十)
- 验证中文名字---正则表达式
- python梦幻西游鼠标偏移_【按键盒子】梦幻西游解决鼠标漂移问题
- python抢票系统代码及解说_python抢票程序
- Net5环境下Aspose.cell与Aspose.pdf最新版21.3全系列 excel转pdf,pdf拼页打印,去水印等
热门文章
- JBoss日志文件配置
- 高性能分布式计算与存储系统设计概要(上)(转)
- 用OpenCV建立一幅只有几个像素且值可以自定义的图像,并输出保存到硬盘的方法
- unity3d 数学基础与数学辅助类
- 3w最简单led灯电路图_led灯驱动电源电路图大全(六款模拟电路设计原理图详解)...
- wxpython问卷调查界面_调查问卷使用说明书,问卷就要这么设计!
- svn提交及更新时的常见问题
- 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线...
- 开源Web应用中最常见漏洞是XSS和SQLI漏洞
- BZOJ 2055: 80人环游世界 [上下界费用流]