rt,题目中保证 1≤N≤50000,但我要把数组开到 105 才能过,否则 WA 50pts,有没有 dalao 解释一下为什么
50 pts:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define pll pair<ll,ll>
#define ull unsigned long long
using namespace std;
const int N=50015;
const long long LINF=0x3f3f3f3f3f3f3f3fll;
const int IINF=0x3f3f3f3f;
inline void FileIO() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
template<typename Type>
inline void read(Type& res) {
Type x=0,f=1;
char c=' ';
while(!isdigit(c)) {
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
res=x*f;
}
int n,a[N],L[N][2],R[N][2];
int tr[N*30][2],siz[N*30],tot,ans,T[N];
int lg[N],f[N][22];
int Ask(int x,int y){
int len=lg[y-x+1];
return max(f[x][len],f[y-(1<<len)+1][len]);
}
void Insert(int p,int q,int x){
for(int i=30;i>=0;i--){
int bit=x>>i&1;
tr[p][!bit]=tr[q][!bit];
tr[p][bit]=++tot;
siz[tr[p][bit]]=siz[tr[q][bit]]+1;
p=tr[p][bit];
q=tr[q][bit];
}
}
int Ask(int p,int q,int x){
int res=0;
for(int i=30;i>=0;i--){
int bit=x>>i&1;
if(siz[tr[p][!bit]]-siz[tr[q][!bit]]>0){
res|=(1<<i);
p=tr[p][!bit];
q=tr[q][!bit];
}
else{
p=tr[p][bit];
q=tr[q][bit];
}
}
return res;
}
signed main(){
// 不开longlong见祖宗!
// 检查数组大小!
// 禁止在int乘int时不开longlong!
// 注意输出格式!
// STL数据类型拷贝赋值时间复杂度是 O(N)!
// 读入单个字符要用字符串,防毒瘤数据!
// (1<<63)爆ll,(1<<31)爆int!
// 比赛结束前5min,检查上述7项,并编译运行!!!!!
// -std=c++14 -O2 -Wall -Wextra -Wshadow -Wl,--stack=536870912
read(n);
int mx=0;
for(int i=1;i<=n;i++){
read(a[i]);
mx=max(a[i],mx);
T[i]=++tot;
f[i][0]=a[i];
Insert(T[i],T[i-1],a[i]);
}
stack<pii> s;
s.push(make_pair(IINF,0));
for(int i=1;i<=n;i++){
while(s.size()&&a[i]>=s.top().first) s.pop();
L[i][0]=s.top().second;
s.push(make_pair(a[i],i));
}
while(s.size()) s.pop();
s.push(make_pair(IINF,n+1));
for(int i=n;i;i--){
while(s.size()&&a[i]>=s.top().first) s.pop();
R[i][0]=s.top().second;
s.push(make_pair(a[i],i));
}
for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int j=1;j<=lg[n];j++){
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
for(int i=1;i<=n;i++){
int l=1,r=L[i][0]-1,res=0;
while(l<=r){
int mid=(l+r)>>1;
if(Ask(mid,L[i][0]-1)>a[i]) res=mid,l=mid+1;
else r=mid-1;
}
L[i][1]=res;
}
for(int i=1;i<=n;i++){
int l=R[i][0]+1,r=n,res=n+1;
while(l<=r){
int mid=(l+r)>>1;
if(Ask(R[i][0]+1,mid)>a[i]) res=mid,r=mid-1;
else l=mid+1;
}
R[i][1]=res;
}
for(int i=1;i<=n;i++){
if(a[i]==mx) continue;
int res1=Ask(T[R[i][0]-1],T[L[i][1]],a[i]);
int res2=Ask(T[R[i][1]-1],T[L[i][0]],a[i]);
ans=max({ans,res1,res2});
}
printf("%d\n",ans);
return 0;
}
```cpp
100 pts:
```cpp
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define pll pair<ll,ll>
#define ull unsigned long long
using namespace std;
const int N=100015;
const long long LINF=0x3f3f3f3f3f3f3f3fll;
const int IINF=0x3f3f3f3f;
inline void FileIO() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
template<typename Type>
inline void read(Type& res) {
Type x=0,f=1;
char c=' ';
while(!isdigit(c)) {
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
res=x*f;
}
int n,a[N],L[N][2],R[N][2];
int tr[N*30][2],siz[N*30],tot,ans,T[N];
int lg[N],f[N][22];
int Ask(int x,int y){
int len=lg[y-x+1];
return max(f[x][len],f[y-(1<<len)+1][len]);
}
void Insert(int p,int q,int x){
for(int i=30;i>=0;i--){
int bit=x>>i&1;
tr[p][!bit]=tr[q][!bit];
tr[p][bit]=++tot;
siz[tr[p][bit]]=siz[tr[q][bit]]+1;
p=tr[p][bit];
q=tr[q][bit];
}
}
int Ask(int p,int q,int x){
int res=0;
for(int i=30;i>=0;i--){
int bit=x>>i&1;
if(siz[tr[p][!bit]]-siz[tr[q][!bit]]>0){
res|=(1<<i);
p=tr[p][!bit];
q=tr[q][!bit];
}
else{
p=tr[p][bit];
q=tr[q][bit];
}
}
return res;
}
signed main(){
// 不开longlong见祖宗!
// 检查数组大小!
// 禁止在int乘int时不开longlong!
// 注意输出格式!
// STL数据类型拷贝赋值时间复杂度是 O(N)!
// 读入单个字符要用字符串,防毒瘤数据!
// (1<<63)爆ll,(1<<31)爆int!
// 比赛结束前5min,检查上述7项,并编译运行!!!!!
// -std=c++14 -O2 -Wall -Wextra -Wshadow -Wl,--stack=536870912
read(n);
int mx=0;
for(int i=1;i<=n;i++){
read(a[i]);
mx=max(a[i],mx);
T[i]=++tot;
f[i][0]=a[i];
Insert(T[i],T[i-1],a[i]);
}
stack<pii> s;
s.push(make_pair(IINF,0));
for(int i=1;i<=n;i++){
while(s.size()&&a[i]>=s.top().first) s.pop();
L[i][0]=s.top().second;
s.push(make_pair(a[i],i));
}
while(s.size()) s.pop();
s.push(make_pair(IINF,n+1));
for(int i=n;i;i--){
while(s.size()&&a[i]>=s.top().first) s.pop();
R[i][0]=s.top().second;
s.push(make_pair(a[i],i));
}
for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int j=1;j<=lg[n];j++){
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
for(int i=1;i<=n;i++){
int l=1,r=L[i][0]-1,res=0;
while(l<=r){
int mid=(l+r)>>1;
if(Ask(mid,L[i][0]-1)>a[i]) res=mid,l=mid+1;
else r=mid-1;
}
L[i][1]=res;
}
for(int i=1;i<=n;i++){
int l=R[i][0]+1,r=n,res=n+1;
while(l<=r){
int mid=(l+r)>>1;
if(Ask(R[i][0]+1,mid)>a[i]) res=mid,r=mid-1;
else l=mid+1;
}
R[i][1]=res;
}
for(int i=1;i<=n;i++){
if(a[i]==mx) continue;
int res1=Ask(T[R[i][0]-1],T[L[i][1]],a[i]);
int res2=Ask(T[R[i][1]-1],T[L[i][0]],a[i]);
ans=max({ans,res1,res2});
}
printf("%d\n",ans);
return 0;
}