ZOJ 3597

题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你被允许选择一个连续的Q个靶子,使得这P把枪所打到的靶子的数目最多,问打到的靶子数目的期望值是多少。

这题通过简单的转化就可以转换成为另一个模型:

如果第a把枪可以打到第b个靶子,那么将其视为二位平面上的一个点(b, a), 问题转化为一个Q * P的矩形最多可以覆盖多少个点。只是有一点需要注意的就是同一把枪只能打到一个靶子,所以在a相等的情况下最多只能覆盖一个b。

至于如何求矩形覆盖点的个数,我这也是第一次写,所以查阅了有关资料。

方法是将矩形的右界作为参考点,找出参考点在哪一个区间(线段)内矩形都可以覆盖到这个点,这样每一个点就对应y相等的一段线段,原题就转化成为了高度y小于P的区间内某一个位置x上的覆盖次数的最大值,可以用线段树的离线操作(扫描线)来完成。

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf (-((LL)1<<40))
#define lson k<<1, L, (L + R)>>1
#define rson k<<1|1, ((L + R)>>1) + 1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i, a, b) for(int i = a; i <= b; i ++) template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
//LL MOD = 987654321; #define OK(i) (i > 0 && p[i - 1].y == p[i].y && p[i].x <= p[i - 1].x + Q - 1) int T, N, M, P, Q, K;
struct Point {
int x, y;
bool operator < (const Point &A) const {
return y == A.y ? x < A.x : y < A.y;
}
}p[MAXM]; struct SegTree {
LL ma[MAXN<<], add[MAXN<<]; void build(int k, int L, int R) {
ma[k] = add[k] = ;
if(L == R) return ;
build(lson); build(rson);
} void pushDown(int k) {
ma[k<<] += add[k]; add[k<<] += add[k];
ma[k<<|] += add[k]; add[k<<|] += add[k];
add[k] = ;
} void update(int k, int L, int R, int l, int r, int val) {
if(R < l || L > r) return ;
if(l <= L && R <= r) { ma[k] += val; add[k] += val; return ; }
pushDown(k);
update(lson, l, r, val);
update(rson, l, r, val);
ma[k] = max(ma[k<<], ma[k<<|]);
} LL query(int k, int L, int R, int l, int r) {
if(R < l || L > r) return ;
if(l <= L && R <= r) return ma[k];
pushDown(k);
return max(query(lson, l, r), query(rson, l, r));
} }segTree; int main()
{
//FIN;
while(~scanf("%d", &T)) while(T--)
{
scanf("%d %d %d %d %d", &N, &M, &P, &Q, &K);
rep (i, , K - ) scanf("%d %d", &p[i].y, &p[i].x);
sort(p, p + K); segTree.build(, , M);
LL ans = , fr = , re = ;
rep (i, P, N) {
while(fr < K && p[fr].y <= i) {
int st = OK(fr) ? p[fr-].x + Q : p[fr].x;
int ed = min(p[fr].x + Q - , M);
segTree.update(, , M, st, ed, );
fr ++;
}
while(i - p[re].y >= P) {
int st = OK(re) ? p[re-].x + Q : p[re].x;
int ed = min(p[re].x + Q - , M);
segTree.update(, , M, st, ed, -);
re ++;
}
ans += segTree.query(, , M, , M);
}
printf("%.2lf\n", (double)ans / (N - P + ));
}
return ;
}

ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)的更多相关文章

  1. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  2. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  3. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  4. poj 3277 City Horizon (线段树 扫描线 矩形面积并)

    题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...

  5. ZOJ-3597-Hit the Target!(线段树+扫描线)

    题解引自:http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474614.html 这题和着题解一块看,看了半天才看懂的....菜菜.... 题意:有 ...

  6. 【学习笔记】线段树—扫描线补充 (IC_QQQ)

    [学习笔记]线段树-扫描线补充 (IC_QQQ) (感谢 \(IC\)_\(QQQ\) 大佬授以本内容的著作权.此人超然于世外,仅有 \(Luogu\) 账号 尚可膜拜) [学习笔记]线段树详解(全) ...

  7. 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))

    扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...

  8. hdu1542 Atlantis (线段树+扫描线+离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  9. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

随机推荐

  1. acdream 1686 梦醒(时钟重合)

    Problem Description 娜娜离开了这个王国,走向远方,在旷野上,娜娜看到了一个大时钟,上面的时针分针秒针都在缓缓转动,那只挥着翅膀的天使又出现了,天使说:“外面天已经亮了,娜娜你别睡过 ...

  2. CodeIgniter 3之Session类库(2)(转)

    CI3的Session的重大改变就是默认使用了原生的Session,这符合Session类库本来的意思,似乎更加合理一些.总体来说,虽然设计理念不同,但为了保证向后兼容性,类库的使用方法与CI2.0的 ...

  3. activiti参考5-任务TASK

    一.概要 1,设计TASK的表主要是:ACT_RU_TASK,ACT_HI_TASKINST(见参考-activiti表): 2,任务主要有:人工任务(usertask),服务任务(serviceta ...

  4. python练习程序(c100经典例15)

    题目: 利用条件运算符的嵌套来完成此题:学习成绩〉=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示. def foo(n): if n>=90: print 'A' , ...

  5. IconRes提供免费高质量的Material风格android官方图标库

    连接地址: http://www.iconres.com/android/index.php

  6. js细节

    1.小心函数中的“s“ getElementsByTagName:得到的是数组 getElementById:得到的是对象 2.js 中设置哪一项被选中 subject.selectedIndex = ...

  7. 跨平台移动开发工具:PhoneGap与Titanium全方位比拼

    PhoneGap和Appcelerator Titanium,对于封装和配置移动应用程序而言,二者都是非常受欢迎的开源JavaScript框架.本文为Appcelerator开发者Kevin Whin ...

  8. Oracle的函数返回表类型(转)

    在SQL Server中有表变量,可以在function中方便地返回,习惯SQL Server或者需要把脚本从SQL Server转到Oracle中的朋友可以都会碰到这个问题. Oracle的func ...

  9. myeclipse 10 优化

    一.Myeclipse10修改字体 MyEclipse10是基于Eclipse3.7内核,但在Eclipse的Preferences-〉general-〉 Appearance->Colors ...

  10. db file sequential read (数据文件顺序读取)

    转载:http://www.dbtan.com/2010/04/db-file-sequential-read.html db file sequential read (数据文件顺序读取): db ...