[LuoguP1901]发射站

一个本题不太寻常的解法。(需要正解的可以pass)

貌似题解区没有这么做的,但可能是我眼瞎

\(\text{Part-I:核心思想}\)

对于每一个发射塔,左右都可能有发射的对象,即向左数第一个\(H\)的值大于自己本身\(H\)的值的塔,或向右数第一个\(H\)的值大于自己本身\(H\)的值的塔。

我们逐个考虑。设现在为第\(i\)个发射塔,要确定左边的发射的对象。

首先,没有的情况,即\(i=1\text{ 或 }\max\limits_{1\le k<i}H_k\le H_i\) 时。

若有,那么......

\[\texttt{Binary Search! 二分查找——}\]

有人就要问了:\(H\)不满足单调性,怎么二分?

\(H\)虽然不满足单调性,但是,我们先令\(L_x=\max\limits_{1\le y<x} H_y\),即\(H_1,H_2,...,H_{x-1}\)的最大值,\(L\)一定满足单调性!

对于\(L\)的维护,由于是静态的,所以ST表是个不错的工具。

部分代码如下:

inline void find_left(int p)
{//此处的L存的是结果!!!
//query_max(x,y) 查询的是max{h[x],h[x+1],...,h[y]}。
    if(p==1||query_max(1,p-1)<=h[p]) {L[p]=-1;return;}
    int l=1,r=p;
    while(r-l>1)
    {
        int mid=(l+r)>>1;
        if(query_max(mid,p-1)>h[p]) l=mid;
        else r=mid;
    }
    L[p]=l; return;
}

关于右边同理。

\(\text{Part-II:时间复杂度}\)

  • ST表的建立:\(O(n\log_2 n)\)
  • 一次二分:\(O(\log_2 n)\)(ST表的查询一次为\(O(1)\))

\(\therefore \text{时间复杂度为}O(3n\log_2 n)\)

\(\text{Part-III:完整代码}\)

(需开O2)

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 1e6 + 5;
int dp[maxn][25];
int h[maxn],v[maxn];
int n;

inline void init()
{
    register int i,j;
    for(i=1;i<=n;i++)
        dp[i][0]=h[i];
    for(j=1;j < 22;j++)
        for(i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}

inline int query_max(int l,int r)
{
    int temp=log2(r-l+1);
    return max(dp[l][temp],dp[r-(1<<temp)+1][temp]);
}

inline int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return f*x;}
inline void write(int x){if(x<0){putchar('-');x=-x;}if(x>9)write(x/10);putchar(x%10+'0');return;}

int L[maxn],R[maxn];
long long ans[maxn];

inline void find_left(int p)
{
    if(p==1||query_max(1,p-1)<=h[p]) {L[p]=-1;return;}
    int l=1,r=p;
    while(r-l>1)
    {
        int mid=(l+r)>>1;
        if(query_max(mid,p-1)>h[p]) l=mid;
        else r=mid;
    }
    L[p]=l; return;
}

inline void find_right(int p)
{
    if(p==n||query_max(p+1,n)<=h[p]) {R[p]=-1;return;}
    int l=p,r=n;
    while(r-l>1)
    {
        int mid=(l+r)>>1;
        if(query_max(p+1,mid)>h[p]) r=mid;
        else l=mid;
    }
    R[p]=r; return;
}

signed main()
{
    register int i;
    scanf("%d",&n);
    for(i=1;i<=n;i++) h[i]=read(),v[i]=read();
    init();
    for(i=1;i<=n;i++)
        find_left(i),find_right(i);
    for(i=1;i<=n;i++)
    {
        if(L[i]!=-1) ans[L[i]]+=v[i];
        if(R[i]!=-1) ans[R[i]]+=v[i];
    }
    printf("%lld",*max_element(ans+1,ans+1+n));
    return 0;
}

\(OVER.\)

原文地址:https://www.cnblogs.com/-Wallace-/p/12337863.html

时间: 2024-11-05 13:28:45

[LuoguP1901]发射站的相关文章

洛谷P1901 发射站

P1901 发射站 245通过 468提交 题目提供者该用户不存在 标签NOI导刊云端↑ 难度普及/提高- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 大神路过的看一下 输入后面为什么带空格. 有人说是单调队列,但不明明- 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或

Luogu【P1901】发射站(单调栈)

题目链接 题目说明比自己矮的塔收不到自己的能量,摆明了就是单调栈呗. 把比自己矮的全都从栈里弹出去,于是碰到第一个比自己高的.让他接受自己发射的能量. 当然由于发射站发射的能量有两个方向,所以正反两遍. 然后 放代码. #include<cstdio> #include<cstdlib> #include<cctype> using namespace std; long long ans; inline long long max(long long a,long l

发射站

题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收最多能量的发射站接收的能量是多少. 输入格式 第 1 行:一个整数 N; 第 2 到 N+1 行:第 i+1 行有

luogu P1901 发射站

题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收最多能量的发射站接收的能量是多少. 输入格式 第 1 行:一个整数 N; 第 2 到 N+1 行:第 i+1 行有

空間定位能力的提升

VR技术:欺骗大脑的技术. 空间定位系统,若能精确侦测到头盔的位置和移动方向,并迅速传送到电脑,对于VR低延迟有很大帮助,能有效降低眩晕感(更佳的视觉欺骗). 此外,如果也能允许在一个空间内的站姿.坐姿.蹲跳等VR体验(更佳的身体动觉欺骗),眩晕感更低了(沉浸感提高了). 在身体动觉方面,以前,使用者不能完全自由地行走. 现在的HTC Vive让人们可在10*10英尺的空间里行动. 这提升了人们身临其境的体验,例如能够在3D空间内绘图,也能从不同角度观察所绘的创作.这也赢得了迪士尼首席动画师Gl

【NOIP数据结构专项】单调队列单调栈

[洛谷P1901 ]发射站 http://www.luogu.org/problem/show?pid=1901 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收

高清电视标准机顶盒

模擬信號接收電視盒 http://www.taobao.com/product/%E6%A8%A1%E6%93%AC%E4%BF%A1%E8%99%9F%E6%8E%A5%E6%94%B6%E9%9B%BB%E8%A6%96%E7%9B%92.html  香港高清电视标准机顶盒  香港模拟广播    http://zh.wikipedia.org/wiki/%E5%BD%A9%E8%89%B2%E9%9B%BB%E8%A6%96%E5%BB%A3%E6%92%AD%E6%A8%99%E6%BA%

物理层

一.传输介质 1. 双绞线 终端到计算机网,一般用双绞线.电话网也是. 价格便宜,安装方便.可传输模拟信号(电话),数字信号(计算机网络,8芯无屏蔽双绞线UTP). 带宽取决于线的粗细和传输的距离. 3类Cat3--10M bps, 只有100米距离 5类Cat5--100M bps 2. 同轴电缆 基带同轴电缆,数字信号.50欧姆.目前基本被双绞线代替. 宽带同轴电缆,模拟信号,如有线电视.75欧姆. 3. 光缆 单模光缆,直线传输,10千米. 多模光缆,距离2千米. 目前光缆基本用于主干网.

ACdream原创群赛__15

这场感觉题目确实还算可以,不过,说好的每题10s效果上却不理想.这个时限还算比较紧.因为时间不是按绝对的多出几秒来计算,而是几倍来计算的. 比赛做的不好,后面又去做了一下. A:典型的数位DP,一直坑在这里. E:求f(f(f(n)))%p.f()表示斐波那契数.关于求斐波那契数模的循环节是有特定的数学定理和方法的.我也不知道,但是看了结论之后自己会实现了.首先,把p因数分解,ai^pi,显然最终的循环节就等于这些单独因子计算循环节的lcm.同时ai^pi的循环节又是G(ai)*ai^(pi-1