原题链接
题意:
已知一个数组a和数组b,bi是a数组中前i个元素的中位数,现在给定b数组,判断是否可以求出a数组
思路:
假设第b[i]前都满足,那么说明此时b[i]就是a数组中的中位数,现在插入b[i+1]会出现两种情况。
1.如果b[i+1]和b[i]之间没有出现过数,那么只要插入一个b[i+1]再根据大小关系插入一个+inf或者-inf就行了2.如果b[i+1]和b[i]之间出现过数,那么仅插入两个数最多只能使中位数移动一位,并不能移到b[i+1]身上,所以这种情况是不行的。
所以直接树状数组查询中间有没有数字出现过就可以了。
#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 998244353
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
typedef pair<int,int>pa;
const int N = 3e5+7;
int a[N], n, tr[N], vis[N];
char s[N];
vector<int>v;
int lowbit(int x){return x&(-x); };
void update(int x){
for(int i = x;i <= n;i+=lowbit(i)){
tr[i] += 1;
}
}
int query(int x){
int res = 0;
for(int i = x;i >= 1;i-=lowbit(i)){
res += tr[i];
}
return res;
}
int main(){
int _;
scanf("%d", &_);
while(_--){
v.clear();
scanf("%d", &n);
for(int i = 1;i <= n;i++){
vis[i] = 0;
scanf("%d", &a[i]);
v.push_back(a[i]);
}
memset(tr, 0, sizeof(tr));
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for(int i = 1;i <= n;i++){
a[i] = lower_bound(v.begin(), v.end(), a[i])-v.begin()+1;
}
int t1, t2, fla = 0;
update(a[1]);
for(int i = 2;i <= n;i++){
if(a[i]==a[i-1]){
update(a[i]);
continue;
}
if(a[i]>a[i-1]) t2 = query(a[i]-1), t1 = query(a[i-1]);
else t2 = query(a[i-1]-1), t1 = query(a[i]);
if(t2-t1){
fla = 1;
break;
}
update(a[i]);
}
if(fla) printf("NO\n");
else printf("YES\n");
}
return 0;
}