1382E - Mastermind

$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 ans[N];
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");
    }
}

}