bzoj3203: [Sdoi2013]保护出题人 凸包+三分

/**************************************************************
    Problem: 3203
    User: wangyucheng
    Language: C++
    Result: Accepted
    Time:344 ms
    Memory:4396 kb
****************************************************************/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define N 100003
typedef long long ll;
int n;
double d,a[N],x[N],ans=0.0;
struct P{
    double x,y;
    P(double a=0.0,double b=0.0){
     x=a,y=b;
    }
    P operator-(P b){return P(x-b.x,y-b.y);}
    double operator*(P b){return x*b.y-y*b.x;}
}s[N];
double sp(P a,P b){
   return (a.y-b.y)/(a.x-b.x);
}
int main(){
    scanf("%d",&n);
    scanf("%lf",&d);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i],&x[i]);
    double sum =0;
    int top=0;
    for(int i=1;i<=n;i++){
        P p=P(i*d,sum);sum+=a[i];
        while(top>1&&(p-s[top-1])*(s[top]-s[top-1])>=0)top--;
        s[++top]=p;
        p=P(x[i]+i*d,sum);
        int l=1,r=top,m1,m2;
        while(r-l>=3){
           m1=l+(r-l)/3;
           m2=r-(r-l)/3;
           double k1=sp(s[m1],p),k2=sp(s[m2],p);
           if(k1<k2)l=m1;else r=m2;
        }
        double res=0;
        for(int j=l;j<=r;j++)res=max(res,sp(s[j],p));
        ans+=res;   

    }
    printf("%.0lf\n",ans);
}

bzoj3203: [Sdoi2013]保护出题人 凸包+三分

时间: 2024-11-14 09:59:31

bzoj3203: [Sdoi2013]保护出题人 凸包+三分的相关文章

BZOJ3203 SDOI2013 保护出题人 凸包+三分法

题意:给定N组询问和D,初始时集合为空,每组询问先向集合的开头插入一个元素xi,然后给出一个数pi,求最小的yi使得\[{y}_{i}\left({p}_{i}+D\left(i-1 \right) \right)\geq {x}_{i}\] 题解:设Si=$\sum\limits_{j = 1}^i{x}_{j}$,显然yi=$max\left \{ \frac{{S}_{i}-{S}_{j-1}}{x_{i}+D\left ( i-j \right )} \right \},1\leq j\

BZOJ 3203 Sdoi2013 保护出题人 凸包+三分

题目大意:太长自己看 令sumi表示第i个僵尸以及之前的僵尸的体力总和.disi表示第i个僵尸与房屋的初始距离 我们发现我们能消灭一个僵尸当且仅当y>=sumidisi 那么我们要求的显然就是max{sumidisi} 我们将一个僵尸抽象成一个点sumidisi.那么我们发现每一个回合僵尸之间的相对位置是不变的 因此我们能够维护一个凸包.三分就可以 #include <cstdio> #include <cstring> #include <iomanip> #i

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

题目描述 输入 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai 点的僵尸,排头僵尸从距离房子Xi米处开始接近. 输出 一个数,n关植物攻击力的最小总和 ,保留到整数. 样例输入 5 2 3 3 1 1 10 8 4 8 2 3 样例输出 7 题解 凸包+二分 把第 $i$ 只僵尸的血量看作前 $i$ 只僵尸的血量的前缀和,那么就相当于所有僵尸同时受到伤害. 把僵尸的

[bzoj3203][Sdoi2013]保护出题人

人生第一道三分?... 把进攻序列里的前i只僵尸看成一个点,横坐标是第i只僵尸到达的时间,纵坐标是这i只僵尸的血量总和..就是说植物必须在这段时间内输出这些伤害..那么单位时间的输出伤害就是斜率了. 问题就变成了对于若干个点,求从原点到各个点斜率的最大值. 因为D是固定的,而每次新加入僵尸实际就是把原来的点平移..并且相对位置关系不变...所以显然斜率最大的点一定在凸包上= = 每次就新加入一个点并维护凸包,然后三分找出凸包上的点与原点连线斜率的最大值(原点与凸包上各个点连线的斜率是单峰的)就好

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

惊了,我怎么这么菜啊.. 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=3203 (luogu)https://www.luogu.org/problemnew/show/P3299 题解: 先讲正常做法. 设\(S_i\)为\(i\)的前缀和,则显然第\(i\)次答案为\(\max^i_{j=1} \frac{S_i-S_{j-1}}{x_i+id-jd}\) 那么很显然就是要求从一个点\((x_i+id,S_i)\)

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

[BZOJ3203][Sdoi2013]保护出题人 Description Input 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai 点的僵尸,排头僵尸从距离房子Xi米处开始接近. Output 一个数,n关植物攻击力的最小总和 ,保留到整数. Sample Input 5 2 3 3 1 1 10 8 4 8 2 3 Sample Output 7 HINT 第

SDOI2013 保护出题人

Description ?出题人铭铭认为给SDOI2012 出题太可怕了,因为总要被骂,于是他又给SDOI2013 出题了. 参加SDOI2012 的小朋友们释放出大量的僵尸,企图攻击铭铭的家.而你作为SDOI2013的参赛者,你需要保护出题人铭铭. 僵尸从唯一一条笔直道路接近,你们需要在铭铭的房门前放置植物攻击僵尸,避免僵尸碰到房子.第一关,一只血量为a1 点的僵尸从距离房子x1 米处匀速接近,你们放置了攻击力为y1 点/秒的植物进行防御:第二关,在上一关基础上,僵尸队列排头增加一只血量为a2

bzoj-3203 保护出题人

题意: 在一个诡异的植物大战僵尸游戏中,给出n关: 第i关队首僵尸距房门xi,两个僵尸之间间隔为d: 每次在队首添加一个血量为ai的僵尸,其他僵尸不变: 每关在门前放一个攻击力任意的植物,求n关放置植物总攻击力的最小值: n<=100000,其他数据<=10^12: 题解: 题意叙述略诡异..建议还是去看一眼原题: 首先考虑对于每一关的答案,应该是恰好将最难打死的僵尸打死的攻击力值: 令s[i]为i这个僵尸血量与它前面僵尸血量之和,dis[i]为这个僵尸距房门的距离: 那么答案就是ans=ma

保护出题人「SDOI 2013」

题意 有n个关卡,每一关都会在僵尸队列的排头添加一只僵尸,同时排头与家的距离会发生变化.相邻僵尸之间的距离固定为\(d\). 对于每一关,可以放置一颗任意攻击力的植物(每颗植物仅作用于当前关卡).求攻击力总和最小值. 思路 显然\(f[i]=max(\frac{sum[i]-sum[j-1]}{x[i]+d*(i-j)})\),由于斜率没有单调性,所以二分凸包. 另注:题目的取整指的是四舍五入而不是向下取整,恶臭. 代码 #include <bits/stdc++.h> using names