比赛C题求调
查看原帖
比赛C题求调
746930
NO_OI_NO_LIFE楼主2024/5/12 18:11

个人感觉是st表+二分,不知道判断的DS对不对。感觉二分return写的有问题

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000006;
int t,id,n;
int f[N][77],g[N][77],lg[N];
int qmx(int l,int r){
	int k=lg[r-l+1];
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
int qmn(int l,int r){
	int k=lg[r-l+1];
	return min(g[l][k],g[r-(1<<k)+1][k]);
}
int check(int x){
	int lf=1,cnt=0;
	for(int i=2; ;i++){
		if(i>n) break;
		if(qmx(lf,i)-qmn(lf,i)==x){
			lf=i+1,i++;cnt++;continue;
		}
	}
	if(cnt>=2&&lf==n+1) return 2;
	if(lf==n+1) return 1;
	if(qmx(lf,n)-qmn(lf,n)>x) return 1;
	else return 0;
}
int main(){
//	freopen("1558.in","r",stdin);
//	freopen("color.out","w",stdout);
	cin>>t>>id;
	while(t--){
		cin>>n;int l,r;int mx=-1,mn=1e9;
		for(int i=1;i<=n;i++){
			scanf("%d",&f[i][0]);g[i][0]=f[i][0];
			mx=max(mx,f[i][0]);mn=min(mn,f[i][0]);
		}
		if(id==4){
			if(n<4) cout<<"No"<<endl;
			else cout<<"Yes"<<endl;
			continue;
		}
		lg[0]=-1;
		for(int i=1;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]);
				g[i][j]=min(g[i][j-1],g[i+(1<<j-1)][j-1]);
			}
		bool okk=1;l=0,r=mx-mn;
		while(l<r){//cout<<l<<" "<<r<<endl;
			int mid=l+r>>1;
			int ok=check(mid);
			if(ok==2){
				cout<<"Yes"<<endl;okk=0;
				break;
			}
			if(ok) l=mid+1;
			else r=mid-1; 
		}
		if(okk) cout<<"No"<<endl;
	}
	return 0;
}
2024/5/12 18:11
加载中...