传送门:CF
思路:
这道题再做之前应该明确一个点:我们要做的是输出YES或者NO,也就是判断情况是否成立,不是要求出原数组,所以一定存在一个判断条件来决定是否成立。
不难发现当前中位数一定是在上一个中位数的基础上移动不超过1格,所以我们要做的是找到新增加2个数后,(上一次中位数的位置-现在中位数的位置)<=1。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int lowbit(int x)
{
return x & -x;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
vector<int>v(n + 1),pos(n+1);
for (int i = 1; i <= n; i++)
{
cin >> v[i]; pos[i] = v[i];
}
sort(pos.begin() + 1, pos.end());
int len = unique(pos.begin() + 1, pos.end()) - pos.begin()-1;
map<int, int >ma;
vector<int>ans(n + 1);
for (int i = 1; i <= len; i++)ma[pos[i]] = i;
vector<int>sum(n + 1);
function<void(int)>build = [&](int t)
{
for (int i = t; i <= len; i += lowbit(i))
{
sum[i]++;
}
};
function<int(int)>find_tre = [&](int t)
{
int kase = 0;
for (int i = t; i > 0; i -= lowbit(i))
{
kase += sum[i];
}
return kase;
};
vector<int>flag(n + 1);
bool fff = 0;
build(ma[v[1]]);
flag[ma[v[1]]] = 1;
for (int i = 2; i <= n; i++)
{
if (flag[ma[v[i]]] == 0)
{
build(ma[v[i]]);
flag[ma[v[i]]]=1;
}
//ans[i] = find_tre(ma[v[i]]);
//cout << "find::" << ans[i] << ' ' << i << endl;
if (abs(find_tre(ma[v[i-1]]) - find_tre(ma[v[i]])) > 1)
{
fff = 1;
cout << "NO" << endl;
break;
}
}
if (!fff)cout << "YES" << endl;
}
return 0;
}