题目大意:

http://www.lydsy.com/JudgeOnline/problem.php?id=3203

题解

首先我们考虑对一大波僵尸来袭的情况进行分析

假设来袭的僵尸是\(\{ a_1,a_2,a_3,...,a_n\}\)

那么距离分别为\(\{dis,dis+d,dis+d*2,...,dis+d*(n-1)\}\)

那么我们知道,在这波僵尸中,我们应该取到的最小的攻击速度为

\(max{\frac{sum_i}{dis_i}}\)

其中\(sum_n = \sum_{i=1}^{n}a_i,dis_i = dis + (i-1)*d\)

然后我们把这个式子转化到原序列中,发现式子变成了下面这个样子

假设排头的僵尸是\(p\) :

那么有\(ans_p = max_{i=1}^n\{\frac{sum_p - sum_{i-1}}{(dis_p+p*d - i*d)}\}\)

而我们的目的就是最小化\(\sum_{i=1}^nans_i\)

我们观察上面关于\(ans_p\)的式子,发现这实际上是两个点的斜率

即\((dis_p+p*d,sum_p)\)和\((i*d,sum_{i-1})\)两个点的斜率

所以我们枚举每个p,然后对于每个p都计算出所有的\((i*d,sum_{i-1})\)

然后再取斜率最大值即可...

TLE

我们发现每次针对不同的p计算的时候\((i*d,sum_{i-1})\)居然都是相同的!

所以我们根本不需要每次都重新计算

那么每次当我们枚举到一个p的时候,计算所有满足\(i\leq p\)的点中与其最大斜率即可

那怎么计算这个最大斜率呢??

我们知道每次加入的点在横纵坐标上一定都比上一次加入的点要大

说起来比较矛盾,但是我们需要维护一个不会将任何点包括的"上凸壳"

然后在这个"上凸壳"上的斜率明显是一个单峰函数,所以我们三分即可.

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(ll &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 100010;
const double eps = 1e-9;
inline int dcmp(const double &x){
if(x < eps && x > -eps) return 0;
return x > 0 ? 1 : -1;
}
struct Point{
double x,y;
Point(const double &a = 0,const double &b = 0){x=a;y=b;}
void print(){
printf("Point : (%lf,%lf)\n",x,y);
}
};
typedef Point Vector;
inline Vector operator + (const Vector &a,const Vector &b){
return Vector(a.x+b.x,a.y+b.y);
}
inline Vector operator - (const Vector &a,const Vector &b){
return Vector(a.x-b.x,a.y-b.y);
}
inline double cross(const Vector &a,const Vector &b){
return a.x*b.y - a.y*b.x;
}
inline double slope(const Point &a,const Point &b){
return (a.y - b.y)/(a.x - b.x);
}
Point p[maxn];int m = 0;
inline void insert(const Point &x){
while(m > 1 && dcmp(cross(p[m] - p[m-1],x - p[m])) <= 0) -- m;
p[++m] = x;
}
ll a[maxn],dis[maxn],sum[maxn];
double solve(const Point &x){
int l = 1,r = m,midx,midy;
while(l <= r-3){
midx = (l+l+r)/3;midy = (l+r+r)/3;
if(slope(p[midx],x) > slope(p[midy],x)) r = midy;
else l = midx;
}
double ans = .0;
for(int i=l;i<=r;++i) ans = max(ans,slope(p[i],x));
return ans;
}
int main(){
ll n,d;read(n);read(d);
for(int i=1;i<=n;++i){
read(a[i]);read(dis[i]);
sum[i] = sum[i-1] + a[i];
}double ans = .0;
for(int i=1;i<=n;++i){
insert(Point(i*d,sum[i-1]));
ans += solve(Point(dis[i]+i*d,sum[i]));
}printf("%.0f\n",ans);
getchar();getchar();
return 0;
}

bzoj 3203: [Sdoi2013]保护出题人 凸包的更多相关文章

  1. BZOJ 3203 [SDOI2013]保护出题人 (凸包+三分)

    洛谷传送门 题目大意:太长略 每新加入一个僵尸,容易得到方程$ans[i]=max{\frac{sum_{i}-sum_{j-1}}{s_{i}+d(i-j)}}$ 即从头开始每一段僵尸都需要在规定距 ...

  2. BZOJ 3203 Luogu P3299 [SDOI2013]保护出题人 (凸包、斜率优化、二分)

    惊了,我怎么这么菜啊.. 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=3203 (luogu)https://www.lu ...

  3. 【BZOJ】3203: [Sdoi2013]保护出题人(几何+三分+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3203 wa无数次QAQ,犯sb错....一是数组没有引用...二是输出转成了int(越界了sad). ...

  4. 【bzoj3203】[Sdoi2013]保护出题人 凸包+二分

    题目描述 输入 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai 点的 ...

  5. [BZOJ3203][SDOI2013]保护出题人(凸包+三分)

    https://www.cnblogs.com/Skyminer/p/6435544.html 先不要急于转化成几何模型,先把式子化到底再对应到几何图形中去. #include<cstdio&g ...

  6. 【BZOJ3203】[Sdoi2013]保护出题人 二分+凸包

    [BZOJ3203][Sdoi2013]保护出题人 Description Input 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + ...

  7. [BZOJ3203] [SDOI2013]保护出题人(二分+凸包)

    [BZOJ3203] [SDOI2013]保护出题人(二分+凸包) 题面 题面较长,略 分析 对于第i关,我们算出能够打死前k个个僵尸的最小能力值,再取最大值就可以得到\(y_i\). 前j-1个僵尸 ...

  8. 洛谷 P3299 [SDOI2013]保护出题人 解题报告

    P3299 [SDOI2013]保护出题人 题目描述 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企 ...

  9. [SDOI2013]保护出题人

    题目 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企图攻击铭铭的家.而你作为SDOI2013的参赛者 ...

随机推荐

  1. 省队集训 Day7 选点游戏

    [题目大意] 维护一个$n$个点的图,$m$个操作,支持两个操作: 1. 连接$(u, v)$这条边: 2. 询问$u$所在的联通块中,能选出的最大合法的点数. 一个方案是合法的,当且仅当对于所有被选 ...

  2. 【BZOJ】1954: Pku3764 The xor-longest Path

    [算法]trie树+xor路径 [题解] 套路1:统计从根到每个点的xor路径和,由于xor的自反性,两个点到根的xor路径和异或起来就得到两点间路径和. 然后问题就是找到n个值中异或值最大的两个值, ...

  3. 01-QQ 3-最终重构版 Demo示例程序源代码

      源代码下载链接:01-QQ 3.zip292.5 KB // QQAppDelegate.h Map // //  QQAppDelegate.h //  01-QQ // //  Created ...

  4. 大聊Python----通过Socket实现简单的ssh客户端

    光只是简单的发消息.收消息没意思,干点正事,可以做一个极简版的ssh,就是客户端连接上服务器后,让服务器执行命令,并返回结果给客户端. #ssh_client.py import socket cli ...

  5. javascript 变量类型判断

    一.typeof 操作符 对于Function, String, Number ,Undefined 等几种类型的对象来说,他完全可以胜任,但是为Array时 "); typeof arr ...

  6. 【Mysql优化】索引覆盖

    索引覆盖 是指 如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据.这种查询速度非常快,称为”索引覆盖”,比平时的查询少一次到磁盘读数据的操作.(索引正好覆盖到查 ...

  7. static class 和 non static class 的区别

    static class non static class 1.用static修饰的是内部类,此时这个 内部类变为静态内部类:对测试有用: 2.内部静态类不需要有指向外部类的引用: 3.静态类只能访问 ...

  8. python基础===进程,线程,协程的区别(转)

    本文转自:http://blog.csdn.net/hairetz/article/details/16119911 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自 ...

  9. myeclipse创建的项目发布不了文档

    进入MyEclipse的工作目录下/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.ast.dep ...

  10. 高性能网络编程(1)—accept建立连接‍(待研究)

    阿里云博客上一篇感觉还不错的文章,待研究,原文链接如下: http://blog.aliyun.com/673?spm=5176.7114037.1996646101.3.oBgpZQ&pos ...