#构造,二分#[AGC006B] [AGC006D] Median Pyramid 分析(Easy) 代码 分析(Hard) 代码(Hard)

Easy
Hard


(X=1)(X=2n-1)无解,否则在正中间构造(X-1,X,X+1)
其余位置升序铺入剩余数,
(X-1)左侧数大于(X-1)那么(X-1)(X)上方必定为(X)
(X+1)上方为(X+1),可以发现比原来更接近(X),显然到塔尖答案即为(X)
(X+1)右侧数小于(X+1)的情况同理


代码

#include <cstdio>
#define rr register
using namespace std;
int n,x,t;
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	scanf("%d%d",&n,&x);
	if (x==1||x==2*n-1) return !puts("No");
	puts("Yes"),t=1;
	for (rr int i=1;i<n-1;++i){
		while (x-1<=t&&t<=x+1) ++t;
		print(t++),putchar(10);
	}
	print(x-1),putchar(10),
	print(x),putchar(10),
	print(x+1),putchar(10);
	for (rr int i=1;i<n-1;++i){
		while (x-1<=t&&t<=x+1) ++t;
		print(t++),putchar(10);
	}
	return 0;	
}

分析(Hard)

考虑二分答案,令(b[i]=a[i]leq ans)
按照Easy越接近中间越有可能成为答案
所以越靠中间只要存在两个1,这个答案就可以被传上去,
否则如果存在两个0显然不行,否则如果都判断不了就用(b[1])判断


代码(Hard)

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int n,a[200011];
inline signed iut(){
	rr int ans=0,f=1; rr char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans*f;
}
inline bool check(int k){
	for (rr int i=0;i<n-1;++i){
		if ((a[n-i-1]>k&&a[n-i]>k)||(a[n+i]>k&&a[n+i+1]>k)) return 0;
		if ((a[n-i-1]<=k&&a[n-i]<=k)||(a[n+i]<=k&&a[n+i+1]<=k)) return 1;
	}
	return a[1]<=k;
}
signed main(){
	n=iut();
	for (rr int i=1;i<=n*2-1;++i) a[i]=iut();
	rr int l=2,r=2*(n-1);
	while (l<r){
		rr int mid=(l+r)>>1;
		if (check(mid)) r=mid;
		    else l=mid+1;
	} 
	return !printf("%d",l);	
}