https://codeforces.com/contest/1530/problem/D
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include<set>
using namespace std;
int n;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
vector<int> op(n+1),cnt(n+1);//op存输入,cnt记录出现次数
set<int> _in,_out;//记录没收到礼物和还没送出礼物的
int res=0;
for(int i=1;i<=n;i++)cin>>op[i],cnt[op[i]]++;//尽量满足越多的人
vector<int> ans(n+1);//记录答案
for(int i=1;i<=n;i++){
if(cnt[op[i]]>=1)ans[i]=op[i],cnt[op[i]]=-1,res++;
}
for(int i=1;i<=n;i++)if(cnt[i]==0)_in.insert(i);//没收到的人
for(int i=1;i<=n;i++)if(!ans[i])_out.insert(i);//没送出的人
// for(auto i:_in)cout<<i<<" ";
// cout<<endl;
// for(auto i:_out)cout<<i<<" ";
// cout<<endl;
// cout<<_in.size()<<" "<<_out.size()<<"\n";
vector<int> arr;//用来存既没有收到也没送出的
for(int i=1;i<=n;i++)
{
if(_in.count(i)&&_out.count(i)){
arr.push_back(i);
_in.erase(i),_out.erase(i);
}
if(arr.size()==2)//存在两个就相互送掉
{
ans[arr[0]]=arr[1];
ans[arr[1]]=arr[0];
arr.clear();
}
}
if(arr.size()&&_in.size())//集合没空就处理掉剩下(既没有收到也没送出的)
{
int x=*(_in.begin());
int y=*(_out.begin());
ans[arr[0]]=x;
ans[y]=arr[0];
_in.erase(x);
_out.erase(y);
arr.clear();
}
while(_in.size())//处理集合内剩下的
{
int x=*(_in.begin());
int y=*(_out.begin());
ans[y]=x;
_in.erase(x);
_out.erase(y);
}
if(arr.size())
{
ans[arr[0]]=arr[0];
for(int i=1;i<=n;i++)
{
if(i!=arr.back()&&op[i]==op[arr.back()])
{
swap(ans[i],ans[arr.back()]);
break;
}
}
}
cout<<res<<"\n";
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
cout<<"\n";
}
return 0;
}