关于数组大小
查看原帖
关于数组大小
1066579
XP3301_Pipi楼主2024/7/31 18:50

rt,题目中保证 1≤N≤500001\leq N \leq 50000,但我要把数组开到 10510^5 才能过,否则 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;
}
2024/7/31 18:50
加载中...