$n\leq 10^5,1\leq a[i]\leq n+1$
询问是否存在有$y$个元素相同,$x$个元素一一对应的序列。
可以知道对于某些元素,$mx$=某个元素出现最多的次数,
$if (2\times mx> len )$则会只有$2(len-mx)$个元素,可以对应不同。
考虑假设选完了$x$个元素,要让剩下的$n-x$个元素有$y-x$互相不同。(如果多的话,显然可以让$y$个元素变成$z\notin a_i$。),反之如果少就没办法了。
所以贪心的想,就是要让$n-x$的$mx$尽量小,用优先队列维护下取$x$的过程即可
以上解决了$YES,NO$
考虑最终结果就是$a_i\rightarrow b_i$,考虑把每个数字存进$vector$,记录需要变成哪些。
一下考虑$n-x$那些元素
- 形成对应不相同只需要所有元素移动$(n-x)/2$格
- $max(2\times max-len,0)$的元素是无法对应不相同的,改成$z$即可
- 多出来的部分$y-x$,变成$z$
代码
```c++
include
using namespace std;
typedef long long ll;
define pii pair
define mk make_pair
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < ‘0’ || c > ‘9’)
{
if (c == ‘-‘)
f = -1;
c = getchar();
}
while (c >= ‘0’ && c <= ‘9’)
x = (x << 1) + (x << 3) + c - ‘0’, c = getchar();
return x * f;
}
vector
int a[N], cnt[N];
int main()
{
int T = read();
while (T--)
{
int n = read(), x = read(), y = read();
for (int i = 1; i <= n + 1; i++)
cnt[i] = 0, ans[i].clear();
for (int i = 1; i <= n; i++)
{
a[i] = read();
cnt[a[i]]++;
}
int z = 0;
priority_queue<pii> q;
for (int i = 1; i <= n + 1; i++)
{
if (cnt[i] == 0)
z = i;
else
q.push(mk(cnt[i], i));
}
for (int i = 1; i <= x; i++)
{
pii now = q.top();
q.pop();
ans[now.second].push_back(now.second);
now.first--;
q.push(mk(now.first, now.second));
}
int mx = 0;
vector<int> tmp;
while (!q.empty())
{
pii now = q.top();
q.pop();
for (int i = 1; i <= now.first; i++)
tmp.push_back(now.second);
mx = max(mx, now.first);
}
int tot = n - x;
if ((tot - mx) * 2 >= y - x)
{
puts("Yes");
if (2 * mx <= tot)
{
int si = tmp.size();
for (int i = 0; i < y - x; i++)
ans[tmp[i]].push_back(tmp[(i + mx) % si]);
for (int i = y - x; i < si; i++)
ans[tmp[i]].push_back(z);
}
else
{
int si = tmp.size();
int k = 2 * mx - tot;
for (int i = k; i < k + (y - x); i++)
ans[tmp[i]].push_back(tmp[(i + mx - k) % si]);
for (int i = 0; i < k; i++)
ans[tmp[i]].push_back(z);
for (int i = k + (y - x); i < si; i++)
ans[tmp[i]].push_back(z);
}
// for (int i = 1; i <= n; i++)
// cout << a[i] << " ";
// cout << endl;
for (int i = 1; i <= n; i++)
{
int x = ans[a[i]].back();
ans[a[i]].pop_back();
printf("%d ", x);
}
printf("\n");
}
else
{
puts("NO");
}
}
}