cf Round #641 (Div. 2) D. Orac and Medians 思维

显然当某个区间(长度大于1)的中位数为k时,整个区间都可以变成k  但我们很难去找所有子区间的中位数 来确定它们是否为k 

我们得换个思路:https://www.luogu.com.cn/blog/Caro23333/codeforces-round-641-div1b-orac-and-medians-zhong-wen-ti-xie

我们假设

Ai==k Bi=1

Ai<k Bi=0

Ai>k Bi=2

首先 数组里面必须包含k这个值  

其次 对于每个长度为3的区间 若这个区间存在 至少两个大于等于k的数  那么就是可行的 (n=1和n=2时我们特判一下)

 显然 如果每个长度为3的区间只有至多一个大于等于k 的数 那么这个数不可能作为中位数

当一个长度为3的区间有两个及以上的时候 

{Bi,Bi+1,Bi+2} 可以分别为 {0,1,1},{0,1,2},{1,1,2},{1,1,1}的排列  它们对应区间的中位数都为k 显然满足条件

或者 为 {1,2,2} 的排列 我们可以选相邻的1和2 把它们变成1 就变成了上述{1,1,2}的排列

或者 为{0,2,2},{2,2,2}的排列 这些排列都没有1 但是我们知道数组内是肯定有1的  我们可以先以2为中位数 不断合并区间  等到边界的2和数组内的1相邻的时候  我们就可以把它们全变成1了  

综上所述 结论成立

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int a[N];
int main(){
	int n,k,t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);
		int flag = 0;
		for(int i = 1; i <= n; i++){
			scanf("%d",&a[i]);
			if(a[i]==k) flag=1;
		}
		if(!flag){
			puts("no");
			continue;
		}
		if(n==1){
			puts("yes");
			continue;
		}
		if(n==2){
			if(a[1]>=k&&a[2]>=k){
				puts("yes");
			}else{
				puts("no");
			}
			continue;
		}
		flag=0;
		int p = 0;
		for(int i = 3; i <= n; i++){
			p=(a[i-2]>=k)+(a[i-1]>=k)+(a[i]>=k);
			if(p>=2){
				flag=1;
				break;
			}
		}
		if(flag) puts("yes");
		else puts("no");
	}
	return 0;
}
原创文章 85 获赞 103 访问量 2474

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/106122213