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

题目大意:太长自己看

令sumi表示第i个僵尸以及之前的僵尸的体力总和。disi表示第i个僵尸与房屋的初始距离

我们发现我们能消灭一个僵尸当且仅当y>=sumidisi

那么我们要求的显然就是max{sumidisi}

我们将一个僵尸抽象成一个点sumidisi。那么我们发现每一个回合僵尸之间的相对位置是不变的

因此我们能够维护一个凸包。三分就可以

#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define M 100100
#define EPS 1e-7
using namespace std;
typedef long double ld;
struct Point{
    ld x,y;
    Point() {}
    Point(ld _,ld __):
        x(_),y(__) {}
    friend ld Get_Slope(const Point &p1,const Point &p2)
    {
        return (p1.y-p2.y)/(p1.x-p2.x);
    }
}O,stack[M];int top;
int n;
long long d,a[M],sum[M];
ld ans;
void Insert(const Point &p)
{
    while( top>=2 && Get_Slope(stack[top-1],stack[top]) >= Get_Slope(stack[top],p) - EPS )
        top--;
    stack[++top]=p;
}
ld Trisection()
{
    int i,l=1,r=top;
    while(r-l>=3)
    {
        int l_mid=(l+l+r)/3,r_mid=(l+r+r)/3;
        ld _l=Get_Slope(stack[l_mid],O);
        ld _r=Get_Slope(stack[r_mid],O);
        if(_l>_r)
            r=r_mid;
        else
            l=l_mid;
    }
    ld re=0;
    for(i=l;i<=r;i++)
        re=max(re,Get_Slope(stack[i],O));
    return re;
}
int main()
{
    int i;
    long long x;
    cin>>n>>d;
    for(i=1;i<=n;i++)
    {
        #ifdef PoPoQQQ
            scanf("%I64d%I64d",&a[i],&x);
        #else
            scanf("%lld%lld",&a[i],&x);
        #endif
        sum[i]=sum[i-1]+a[i];
        Insert(Point(i*d,sum[i-1]));
        O=Point(i*d+x,sum[i]);
        ans+=Trisection();
    }
    cout<<fixed<<setprecision(0)<<ans<<endl;
    return 0;
}
时间: 2024-12-18 13:40:02

BZOJ 3203 Sdoi2013 保护出题人 凸包+三分的相关文章

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

/************************************************************** Problem: 3203 User: wangyucheng Language: C++ Result: Accepted Time:344 ms Memory:4396 kb ****************************************************************/ #include<iostream> #include&l

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 保护出题人 凸包+三分法

题意:给定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\

【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]保护出题人 二分+凸包

[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

[bzoj3203][Sdoi2013]保护出题人

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

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