Array Shuffling

该博客讨论了一种与数组操作和悲伤度相关的算法问题。在给定长度为n的数组a中,目标是找到一个数组b,它是a的排列,但能导致最大的「悲伤度」,即通过交换元素达到a所需的最小操作次数。题目提供了一个结论:当数组没有重复数字时,形成的环数最少,因此通过构造重复数字的环并按特定顺序排列,可以最大化交换次数。代码示例展示了如何实现这一策略来解决这个问题。
摘要由CSDN通过智能技术生成

CF  Codeforces Global Round 20  F1题

oolimry has an array aa of length nn which he really likes. Today, you have changed his array to bb, a permutation of aa, to make him sad.

Because oolimry is only a duck, he can only perform the following operation to restore his array:

  • Choose two integers i,ji,j such that 1≤i,j≤n1≤i,j≤n.
  • Swap bibi and bjbj.

The sadness of the array bb is the minimum number of operations needed to transform bb into aa.

Given the array aa, find any array bb which is a permutation of aa that has the maximum sadness over all permutations of the array aa.

Input

Each test contains multiple test cases. The first line contains a single integer tt (1≤t≤1041≤t≤104)  — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105)  — the length of the array.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n)  — elements of the array aa.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, print nn integers b1,b2,…,bnb1,b2,…,bn — describing the array bb. If there are multiple answers, you may print any.

Example

input

Copy

2
2
2 1
4
1 2 3 3

output

Copy

1 2
3 3 2 1

Note

In the first test case, the array [1,2][1,2] has sadness 11. We can transform [1,2][1,2] into [2,1][2,1] using one operation with (i,j)=(1,2)(i,j)=(1,2).

In the second test case, the array [3,3,2,1][3,3,2,1] has sadness 22. We can transform [3,3,2,1][3,3,2,1] into [1,2,3,3][1,2,3,3] with two operations with (i,j)=(1,4)(i,j)=(1,4) and (i,j)=(2,3)(i,j)=(2,3) respectively.

思路:

本题结论:

1.在两数相交换时:交换次数的上界是 n - cnt (cnt为环数)

2.就是在一个没有重复数字的数组中,它的环数就是1,将最后一个数放到第一个的位置,或者第一个位置的数放到最后一个位置,剩下的数向后移一位或者向前移一位,这样在两两数交换时所需次数最多。

思路:1.首先是如何能让环最少呢?就是当一个数组里面没有重复的值时,那么环数就是1,所以我们可以将不重复的数组成一个环,剩下重复的数继续挑选出不重复的在组成环,直到每个数都被挑过了。那么我们是不是只要将重复次数相同放入不同的环中即可。2.与我们做好的环进行比较,因为我们想要这个数移动一下变成所需移动次数最多的那种情况,所以我们根据当前的数(大小/值)才能做出判断,也就是让它是不重复的递增出现,也就是第一个位置移到第二位置,第二个数移到第三个位置……最后一个放在第一个位置。

完整代码:

#include <bits/stdc++.h>

using namespace std;

#define int long long
const int mod=1e9+7;

const int N=2e5+20;
int a[N],st[N];
vector<int>v[N];

void solve()
{
    int n;
    cin>>n;
    for(int i=0;i<=n;i++) st[i]=0, v[i].clear();
    int maxx=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        st[a[i]]++;
        maxx=max(maxx,st[a[i]]);
        v[st[a[i]]].push_back(a[i]);
    }

    for(int i=1;i<=maxx;i++)
    {
        sort(v[i].begin(),v[i].end());
    }

    for(int i=1;i<=n;i++)
    {
        int u=st[a[i]];
        st[a[i]]--;
        int num=upper_bound(v[u].begin(),v[u].end(),a[i])-v[u].begin();
        if(num==v[u].size())cout<<v[u][0]<<" ";
        else cout<<v[u][num]<<" ";
    }
    cout<<endl;
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值