A

随便枚举即可。

B

可以发现把前导 $1$ 取完后,先手有必胜策略:

对于 $>1$ 的数,只要使后继局面仍是先手即可。

对于 $1$ ,只要让后手取,即可令后续局面仍是先手。

然后统计前导 $1$ 的数量即可。

C1

考虑一种操作,使得每一个位置最多操作两次。

显然从后面开始操作,没有后效性。

如果相同,直接跳过即可。

如果不相同,就要关注此时位置 $1$ 是否与 位置 $i$ 的值相同,如果相同,操作一下即可。

这种构造方法可以保证操作次数小于 $2n$

C2

优化上述操作过程即可。

注意到翻转序列只需要关注首和尾,

如果需要翻转,就交换首尾。

D

可以发现,如果出现 $[l,r]$ ,使得 $\forall i\in[l+1,r],a_i<a_l$ 且 $a_{r+1}>a_l$ ,则 $[l,r]$ 同一栈中。

这个不难理解,因为如果在不同栈,后面的数会优先弹出。

两个这样的区间可以任意放,但是如果在同一栈中,需要注意顺序。

然后就是能不能0/1背包出解,比赛时降智严重没有想出来背包(屡试屡犯,希望注意!!)。

E

我们设在已经固定下来 $x$ 个位置后,最多出现的数的次数记为 $f$ ,

使得这 $n-x$ 个数中不可避免地会出现至少 $\max\{0,2f-(n-x)\}$ 个数与原序列相同。

那么此时要求 $f$ 尽量地小,这个很容易办到,只需要计数或者堆处理一下即可。

然后构造一个序列,使得 $n-x$ 个数的相同数量为 $\max\{0,2f-(n-x)\}$ 。

有一个很简单的操作,把数取出来,然后重新排序,注意数所代表的位置没有发生改变。

然后把其想象成一个环,旋转 $\lfloor\frac{n-x}{2}\rfloor$ 次,即可得到方案。

容易证明得到的数量为 $\max\{0,2f-(n-x)\}$ 。

const int N=1e5+5;
int a[N],cnt[N],b[N],s[N],p[N];bool vis[N];
struct node
{
    int w,c;
    node(int w=0,int c=0):w(w),c(c){}
    bool operator <(const node &a)const{return c>a.c;}
};
struct heap
{
    node a[N<<1];int len;
    void up(int j){for(int i=j>>1;j>1&&a[j]<a[i];j=i,i=j>>1)swap(a[i],a[j]);}
    void down(int i)
    {
        for(int j=i<<1;j<=len;i=j,j=i<<1)
        {
            if(j<len&&a[j+1]<a[j])++j;
            if(a[j]<a[i])swap(a[j],a[i]);
            else break;
        }
    }
    void push(node x){a[++len]=x;up(len);}
    void pop(){a[1]=a[len--];down(1);}
    node top(){return a[1];}
}q;
vector<int>v[N],e;
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n,A,B;scanf("%d%d%d",&n,&A,&B);memset(b,0,sizeof(b));memset(vis,0,sizeof(vis));
        memset(cnt,0,(n+2)<<2);for(int i=1;i<=n+1;i++)v[i].clear();e.clear();
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),++cnt[a[i]],v[a[i]].push_back(i);
        int re=0;q.len=0;
        for(int i=1;i<=n+1;i++)
        {
            if(!re&&!cnt[i])re=i;
            if(cnt[i])q.push(node(i,cnt[i])),e.push_back(i);
        }
        if(A>B){puts("NO");continue;}
        int ct=0;
        while(ct<A)
        {
            node now=q.top();q.pop();if(cnt[now.w]!=now.c)continue;
            vector<int>::iterator it=v[now.w].begin();++ct;
            b[*it]=now.w;vis[*it]=1;it=v[now.w].erase(it);--cnt[now.w];
            q.push(node(now.w,cnt[now.w]));
        }
        int len=0;
        for(vector<int>::iterator it=e.begin();it!=e.end();)
        {
            if(!cnt[*it])it=e.erase(it);
            else
            {
                for(vector<int>::iterator i=v[*it].begin();i!=v[*it].end();i++)
                {
                    s[++len]=*it;
                    p[  len]=*i;
                }
                ++it;
            }
        }
        int j=len/2,need=0;
        for(int i=1;i<=len;i++)
        {
            s[i]=a[p[(i+j-1)%len+1]];
        }
        for(int i=1;i<=len;i++)b[p[i]]=s[i];
        for(int i=1;i<=n;i++)if(!vis[i]&&b[i]==a[i])b[i]=re,++need; 
        if(need>n-B)puts("NO");
        else
        {
            puts("YES");j=0;
            for(int i=1;i<=n;i++)
                if(!vis[i]&&b[i]!=re&&need<n-B)++need,b[i]=re;
            for(int i=1;i<=n;i++)printf("%d ",b[i]);puts("");
        }
    }
    return 0;
}