Codeforces Round #724 (Div. 2) D. Omkar and Medians

题意

一个长度为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;
}
上一篇:LeetCode-724. 寻找数组的中心下标


下一篇:Codeforces Round #724 (Div. 2) A~D题解