51nod 1423 最大二“货” 单调栈
利用单调栈,高效求出每个区间内的最大值和次大值的亦或值。
先正向扫描,利用单调递减栈,若当前栈为空栈,则直接压入栈中,若为非空栈,弹出栈顶元素,每弹出一个元素,则求一次亦或值,保留最大值
接着进行反向扫描,过程与上相似。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<math.h> #include<cstring> #include<stack> #include<iostream> #include<algorithm> #include<queue> #define MAXSIZE 100005 #define LL long long using namespace std; const LL INF=1e19; LL a[MAXSIZE]; int s[MAXSIZE]; int main() { int n,top; LL maxn = 0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); a[0] = a[n+1] = 0; top = 0; for(int i=1;i<=n+1;i++) { if(top==0) { s[++top] = i; } else { while(top>=1 && a[s[top]] < a[i]) { maxn = max(maxn,a[i]^a[s[top]]); top--; } maxn = max(maxn,a[i]^a[s[top]]); s[++top] = i; } } for(int i=n;i>=0;i--) { if(top==0) { s[++top] = i; } else { while(top>=1 && a[s[top]] < a[i]) { maxn = max(maxn,a[i]^a[s[top]]); top--; } maxn = max(maxn,a[i]^a[s[top]]); s[++top] = i; } } printf("%lld\n",maxn); return 0; }