51nod1423 最大二"货" 单调栈

枚举每个点作为次大值,用单调栈处理出左边 / 右边第一个比它大的数,直接回答

复杂度$O(n)$

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

extern inline char gc() {
    static char RR[23456], *S = RR + 23333, *T = RR + 23333;
    if(S == T) fread(RR, 1, 23333, stdin), S = RR;
    return *S ++;
}
inline int read() {
    int p = 0, w = 1; char c = gc();
    while(c > ‘9‘ || c < ‘0‘) { if(c == ‘-‘) w = -1; c = gc(); }
    while(c >= ‘0‘ && c <= ‘9‘) p = p * 10 + c - ‘0‘, c = gc();
    return p * w;
}

#define sid 200050
#define ri register int

int n, top, ans;
int st[sid], s[sid], L[sid], R[sid];

int main() {
    n = read();
    for(ri i = 1; i <= n; i ++) s[i] = read();

    st[top = 1] = 0; s[0] = 1e9 + 5;
    for(ri i = 1; i <= n; i ++) {
        while(top && s[st[top]] <= s[i]) top --;
        L[i] = st[top]; st[++ top] = i;
    }

    st[top = 1] = n + 1; s[n + 1] = 1e9 + 5;
    for(ri i = n; i >= 1; i --) {
        while(top && s[st[top]] <= s[i]) top --;
        R[i] = st[top]; st[++ top] = i;
    }

    for(ri i = 1; i <= n; i ++) {
        if(L[i] != 0) ans = max(ans, s[i] ^ s[L[i]]);
        if(R[i] != n + 1) ans = max(ans, s[i] ^ s[R[i]]);
    }

    printf("%d\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/reverymoon/p/9557993.html

时间: 2024-10-03 04:05:31

51nod1423 最大二"货" 单调栈的相关文章

浅谈—单调栈

一.概念: 单调栈的本质还是一个栈,只不过是栈的元素从栈底到栈顶单调递增或者是单调递减. 二.单调栈的维护: 每加入一个元素,将这个元素和栈顶元素相比较,(假设你维护的是一个单调递增的栈),如果当前元素大于等于栈顶元素,说明这个元素 没有破坏这个栈的单调性,直接加入:如果当前元素小于栈顶元素,直接向栈中加入元素会破坏栈的单调性,这时我们需要将栈顶元素依次弹出,知道遇到第一个 大于或者等于当前元素的元素,再将该元素压入栈中.时间复杂度O(n),所有的元素都会进栈一次. 三.单调栈的性质: (1)单

单调队列,单调栈相关

说起这个话题,应该很多人会有一种似有所悟,但又不敢确定的感觉. (我差不多就是那样) 没错,这正是因为其中“单调”一词的存在. 那么单调是什么? 学过函数的人都知道单调函数或者函数的单调性吧 其实直白一点说单调,就是一直增或一直减. eg:1,3,5,9就是一个单调增数列,数列中不存在后一个数比前一个数小的现象. 那么同样,在这里谈到的话题也有类似特点. (一)单调队列 其实就是一个符合单调性质的队列,但它同时具有单调的性质以及队列的性质. 使用频率不算高,但却占有至关重要的地位.它的作用很简单

csp-s模拟测试50(9.22)「施工(单调栈优化DP)」&#183;「蔬菜(二维莫队???)」&#183;「联盟(树上直径)」

改了两天,终于将T1,T3毒瘤题改完了... T1 施工(单调栈优化DP) 考场上只想到了n*hmaxn*hmaxn的DP,用线段树优化一下变成n*hmaxn*log但显然不是正解 正解是很**的单调栈 可以想象到最优情况一定是将两端高于中间的一段平原填成一段平的坑,不然如果坑内存在高度差那么我们即使只将一部分抬升也肯定没有用处,并且如果中间的坑已经高于了两端,再向上升也肯定不优,然后就中间的坑可以很很小,也可以很长,对于这个模型我们首先想到n^2*h的DP 设当前表示的f[i]表示当前到了i节

hdu5033 Building (单调栈+)

http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Building Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special

HDU 5033 Building(北京网络赛B题) 单调栈 找规律

做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1257    Accepted Submission(s): 358 Special Judg

BZOJ_1628_[Usaco2007_Demo]_City_skyline_(单调栈)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1628 给出\(n\)个距形的影子,问最少是多少个建筑的?(建筑的影子可以重叠). 分析 用单调栈维护一下. 栈内是可能"延续"到当前位置的之前的影子.那么显然比当前位置高的不可能.如果有和当前位置等高的影子,就延续过来,就可以少一个建筑,否则,就向栈里加入当前位置高度的影子. 1 #include <bits/stdc++.h> 2 using namespace st

51nod1158 单调栈 个人的想法以及分析

单调栈,顾名思义就是保持内部元素单调性并且保证FILO的一种数据结构. 单调栈的代码实现没有什么难度,但是使用姿势难以想到. 在51nod1158中描述了这样一个问题: 给定一个 0-1 矩阵, 求这个矩阵最大的全 1 子矩阵的面积. 问题十分好理解. 现在,我们将这个问题拆分成一些子问题来逐个击破. 首先,为了保证程序操作的规律性与有序性,我们需要把问题等价成一个任意规模下的问题. 比如我们可以将其等价为: 对于第 i 行(列), 求出 以它为边界的最大全 1 子矩阵面积. 这样子我们最终所需

HDU 5033 Building(2014北京网络赛 单调栈+几何)

博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/39494433 Building 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度,给出一个X坐标,高度为0,问X位置能看到的视角是多少度.如图: 图一: 图二: 图一为样例一,图二为样例三,红色部分为高楼,蓝色虚线为视角的最大范围. 解题思路: 由于有10w个点跟10w次询问,所以朴素的算法判断肯定会超时的.所以就需要用单调栈,维护相邻两建筑顶(xi,hi)的

51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线

 区间计数 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{Ai,Ai+1,...,Aj}=max{Bi,Bi+1,...,Bj}] 注:[ ]内表达式为真,则为1,否则为0. 1≤N≤3.5×1051≤Ai,Bi≤N 样例解释: 7个区间分别为:(1,4),(1,5),(2,4),(2,5),(3,3),(3,5),(4,5) Input 第一行一个整数N 第二行