Educational Codeforces Round 131 (Rated for Div. 2)D

这篇文章介绍了一种解决Monocarphic问题的方法,通过给定的按地板取整后的数组重建原始排列。博主分享了如何利用贪心策略找出与输入数组对应的排列,适用于1到5万个测试案例的输入限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Permutation Restoration

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Monocarp had a permutation aa of nn integers 11, 22, ..., nn (a permutation is an array where each element from 11 to nn occurs exactly once).

Then Monocarp calculated an array of integers bb of size nn, where bi=⌊iai⌋bi=⌊iai⌋. For example, if the permutation aa is [2,1,4,3][2,1,4,3], then the array bb is equal to [⌊12⌋,⌊21⌋,⌊34⌋,⌊43⌋]=[0,2,0,1][⌊12⌋,⌊21⌋,⌊34⌋,⌊43⌋]=[0,2,0,1].

Unfortunately, the Monocarp has lost his permutation, so he wants to restore it. Your task is to find a permutation aa that corresponds to the given array bb. If there are multiple possible permutations, then print any of them. The tests are constructed in such a way that least one suitable permutation exists.

Input

The first line contains a single integer tt (1≤t≤1051≤t≤105) — number of test cases.

The first line of each test case contains a single integer nn (1≤n≤5⋅1051≤n≤5⋅105).

The second line contains nn integers b1,b2,…,bnb1,b2,…,bn (0≤bi≤n0≤bi≤n).

Additional constrains on the input:

  • the sum of nn over test cases does not exceed 5⋅1055⋅105;
  • there exists at least one permutation aa that would yield this array bb.

Output

For each test case, print nn integers — a permutation aa that corresponds to the given array bb. If there are multiple possible permutations, then print any of them.

Example

input

Copy

4
4
0 2 0 1
2
1 1
5
0 0 1 4 1
3
0 1 3

output

Copy

2 1 4 3 
1 2 
3 4 2 1 5 
3 2 1 

类似贪心的解法。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<map>
#include<queue>
#include<ctime>
#include<algorithm>
#include<iostream>
#include<set>
#include<sstream>
#include<vector>
#include<stack>
#include<deque>
#include<list>
#include<cctype>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<bitset>
#include<numeric>
#include<array>
#include <cassert>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
const int maxdouble = 0x7f;//127
const int mindouble = 0xfe;//254
const ll mod = 1e9 + 7;

//priority_queue

inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-')
            f=-1;
        ch=getchar();
        if(ch==-1)
            return 0;
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
        
    }
    if(x>=10)
        write(x/10);
    putchar(x%10+'0');
}
/*
int prime(ll n)//1不是,需要特判下
{
    if(n==0||n==1)
        return 0;
    for(ll i=2; i*i<=n; i++)
    {
        if(n % i == 0)
            return 0;
    }
    return 1;
}
 */
ll gcd(ll a,ll b)
{
    return b==0 ? a : gcd(b, a%b);
}
ll lcm(ll a, ll b)
{
    return a*b/gcd(a, b);
}

inline ll check(ll x) //s*(s+1)=x
{
    ll s=sqrt(x*2)+(1e-12);
    if((s*(s+1)/2)==x)
        return s;
    return -1;
}
/*
void getnext()
{
    int i = 0, j = -1;
    nex[0] = -1;
    while(i<m)
    {
        while(j!=-1&&s[i]!=s[j])
            j = nex[j];
        nex[++i] = ++j;
    }
}
*/
ll ksm(ll a, ll b)
{
    ll ret = 1;
    while (b)
    {
        if (b & 1)
            ret = ret * a;// % mod;
        a = a * a;// % mod;
        b >>= 1;
    }
    return ret;
}
ll ksm1(ll a, ll b, ll p)
{
    ll ret = 1;
    while (b)
    {
        if (b & 1)
            ret = ret * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ret;
}
ll multi(ll a, ll x, ll MOD)
{
    ll ans = 0;
    while(x)
    {
        if(x & 1)
            ans = (ans + a) % MOD;
        a = (a + a) % MOD;
        x >>= 1;
    }
    return ans;
}
inline ll mul(ll a,ll b,ll mod)
{
    return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
}

ll exgcd(ll a, ll b, ll &x, ll &y)//返回的r是a, b的最大公约数
{
    if(b==0)
        return x = 1, y = 0, a;
    ll r = exgcd(b, a%b, x, y);
    tie(x, y) = make_tuple(y, x-(a/b)*y);
    return r;
}
/*
 freopen("triangle.in", "r", stdin);
 freopen("triangle.out", "w", stdout);
 ios::sync_with_stdio(false);
 cin.tie(0);
 */
int lowbit(int x) { return log2((x)&(-x)); }
#define endl '\n'
typedef pair<ll,ll> pii;
const double eps = 1e-5;

const int maxn = 5e5 + 500;
ll l[maxn], r[maxn], a[maxn], b[maxn];

int main(void)
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        vector<ll> G[n+1];
        for(int i=1; i<=n; i++)
        {
            scanf("%lld", &b[i]);
            if(b[i]==0)
                l[i] = i+1, r[i] = n;
            else
            {
                l[i] = i/(b[i]+1)+1;
                r[i] = i/b[i];
            }
            G[l[i]].push_back(i);
        }
        priority_queue<array<ll,2>, vector<array<ll, 2> >, greater<> > q;
        for(int i=1; i<=n; i++)
        {
            for(auto t:G[i])
                q.push({r[t], t});
            a[q.top()[1]] = i;
            q.pop();
        }
        for(int i=1; i<=n; i++)
            printf("%lld ", a[i]);
        cout<<endl;
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值