
Yes,否则输出 No。树的形式,实为分治,比较大小,总结结论题(不一定是递推),分治赛高(min,max程序可复制更改,但一定要仔细!!!)
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int t,n,k,p[N];
int s1[N][20],s2[N][20];
void maxs() {
for(int i=1; i<=n; i++)
s1[i][0]=p[i];
for(int j=1; j<=18; j++)
for(int i=1; i<=n; i++) {
if(i+(1<<j)-1>n)
break;
s1[i][j]=max(s1[i][j-1],s1[i+(1<<j-1)][j-1]);
}
}
void mins() {
for(int i=1; i<=n; i++)
s2[i][0]=p[i];
for(int j=1; j<=18; j++)
for(int i=1; i<=n; i++) {
if(i+(1<<j)-1>n)
break;
s2[i][j]=min(s2[i][j-1],s2[i+(1<<j-1)][j-1]);
}
}
int gmn(int l,int r) {
int x=log2(r-l+1);
return min(s2[l][x],s2[r-(1<<x)+1][x]);
}
int gmx(int l,int r) {
int x=log2(r-l+1);
return max(s1[l][x],s1[r-(1<<x)+1][x]);
}
bool check(int l,int r) {
if(l>=r)
return true;
int x=log(r-l+1)/log(2);
int mn=gmn(l,r),mx=gmx(l,r);
for(int i=0; i*2<=r-l; i++) {
if(p[l+i]-k<=mn&&p[l+i]+k>=mx)
return check(l,l+i-1)&&check(l+i+1,r);
if(p[r-i]-k<=mn&&p[r-i]+k>=mx)
return check(r-i+1,r)&&check(l,r-i-1);
}
return false;
}
int main () {
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++)
scanf("%d",&p[i]);
maxs();
mins();
if(check(1,n))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
原文:https://www.cnblogs.com/mysh/p/11789956.html