zoukankan      html  css  js  c++  java
  • Maximum Xor Secondary(单调栈好题)

    Maximum Xor Secondary

     CodeForces - 280B 

    Bike loves looking for the second maximum element in the sequence. The second maximum element in the sequence of distinct numbers x1, x2, ..., xk (k > 1) is such maximum element xj, that the following inequality holds: .The lucky number of the sequence of distinct positive integers x1, x2, ..., xk (k > 1)is the number that is equal to the bitwise excluding OR of the maximum element of the sequence and the second maximum element of the sequence.

    You've got a sequence of distinct positive integers s1, s2, ..., sn (n > 1). Let's denote sequence sl, sl + 1, ..., sr as s[l..r(1 ≤ l < r ≤ n). Your task is to find the maximum number among all lucky numbers of sequences s[l..r].

    Note that as all numbers in sequence s are distinct, all the given definitions make sence.

    Input

    The first line contains integer n (1 < n ≤ 105). The second line contains n distinct integers s1, s2, ..., sn (1 ≤ si ≤ 109).

    Output

    Print a single integer — the maximum lucky number among all lucky numbers of sequences s[l..r].

    Examples

    Input
    5
    5 2 1 4 3
    Output
    7
    Input
    5
    9 8 3 5 7
    Output
    15

    Note

    For the first sample you can choose s[4..5] = {4, 3} and its lucky number is (4 xor 3) = 7. You can also choose s[1..2].

    For the second sample you must choose s[2..5] = {8, 3, 5, 7}.

    题意:给你一串数,问你这一串数的任意子串中的最大值和次大值的异或最大值为多少。

    题解:

      因为一个数可以是很多个区间的最大值,一个数也可以是很多个区间的次大值,所以我们可以以数为研究对象而非一个个区间。

      第一种做法:

            从前往后和从后往前各跑一遍单调栈,每次求的是以当前值为次大值,之前一个比它大的值为最大值,然后这两个值异或。因为单调栈求的就是这个数向左或者向右找第一个比它大的值的位置。所以这个数的位置和栈顶元素的位置构成的区间中,这个数和栈顶元素就是该区间里的次大值和最大值。

    附代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    using namespace std;
    const int maxn=1e5+10;
    int ans;
    stack<int>s;
    stack<int>s2;
    int a[maxn];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=0;i<n;i++)
        {
            while(!s.empty()&&a[s.top()]<a[i])
            {
                s.pop();
            }
            if(!s.empty())
                ans=max(ans,a[i]^a[s.top()]);
            s.push(i);
        }
        for(int i=n-1;i>=0;i--)
        {
            while(!s2.empty()&&a[s2.top()]<a[i])
            {
                s2.pop();
            }
            if(!s2.empty())
            {
                ans=max(ans,a[i]^a[s2.top()]);
            }
            s2.push(i);
        }
        printf("%d
    ",ans);
        return 0;
    } 

    第二种做法:

          %大佬,思路差不多,只是只用求一遍单调栈就可以。从后往前求一遍单调栈然后记录一下对于每一个值它右边第一个比它大的值的位置。然后遍历一遍,每次可以同时求出该数作为最大值和次大值的异或值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<algorithm>
    using namespace std;
    const int maxn=1e5+10;
    stack<int> s;
    int r[maxn];
    int a[maxn];
    int main()
    {
        int n,ans;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=n-1;i>=0;i--)
        {
            while(!s.empty()&&a[s.top()]<a[i])//找每个数右边第一个比它大的数的下标 
            {
                s.pop();
            }
            if(s.empty())
            {
                r[i]=n;
            }
            else
            {
                r[i]=s.top();
            }
            s.push(i);
        }
        ans=0;
        int t;
        for(int i=0;i<n;i++)
        {
            int j=i+1;
            while(j<n)
            {
                t=a[i]^a[j];
                if(t>ans)
                {
                    ans=t;
                }
                if(a[j]>a[i])
                {
                    break;
                }
                j=r[j];
            }
        } 
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    HDU 1728 逃离迷宫
    程序猿求职之道(《程序猿面试笔试宝典》)之不想签约,但也不想轻易放弃机会,怎么办?
    职场生涯(—)
    Python学习笔记24:Django搭建简单的博客站点(二)
    &quot;高可用方案工具包&quot; high availability toolkit 1.1
    [Swift]LeetCode421. 数组中两个数的最大异或值 | Maximum XOR of Two Numbers in an Array
    [Swift]LeetCode420. 强密码检验器 | Strong Password Checker
    [Swift]LeetCode419. 甲板上的战舰 | Battleships in a Board
    [Swift]LeetCode417. 太平洋大西洋水流问题 | Pacific Atlantic Water Flow
    [Swift通天遁地]七、数据与安全-(11)如何检测应用程序中的内存泄露
  • 原文地址:https://www.cnblogs.com/1013star/p/9985414.html
Copyright © 2011-2022 走看看