题意
一个长度为2n-1的数列a,依次求出前1,3,5,...项的中位数,构成新的数列b,给一个b,问是否合法(即找到对应的a)
每次延长2项,即添加2项到数列中,中位数最多只会移动一位(都在左边,向右移动一位,都在右边,向左移动一位,一左一右,中位数不变)
对于b[i],检查b[1]~b[i-1]是否出现在(b[i],b[i+1])的区间内即可
离散化+树状数组
#include<bits/stdc++.h>
using namespace std;
int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
const int MAXN = 200005;
int n;
int a[MAXN];
int sav[MAXN];
int t[MAXN],cnt[MAXN];
void upd(int x,int y){
for(int i=x;i<=n;i+=i&-i)
t[i]+=y;
}
int query(int x){
int ret=0;
for(int i=x;i>0;i-=i&-i)
ret+=t[i];
return ret;
}
int L[MAXN],R[MAXN],E[MAXN];
bool solve(){
n=rd();
int Li=0,Ri=0;
for(int i=1;i<=n;i++) sav[i]=a[i]=rd();
for(int i=0;i<=n;i++){
t[i]=cnt[i]=L[i]=R[i]=E[i]=0;
}
sort(sav+1,sav+1+n);
int tot=unique(sav+1,sav+1+n)-sav-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(sav+1,sav+1+tot,a[i])-sav;
for(int i=1;i<n;i++){
int x=a[i],y=a[i+1];
if(x>y) swap(x,y);
x++;y--;
if(query(y)-query(x-1)>0) return 0;
upd(a[i],1);
}
return 1;
}
int main(){
int T=rd();
while(T--)
if(solve()) puts("YES");
else puts("NO");
return 0;
}