链接
题解
可以发现,每个人往后换一次就
+
+
++
++,往前换一次就
−
−
--
−−
假设第
i
i
i个人最终在的位置是
p
i
p_i
pi,那么最后的权值就是
a
i
−
(
p
i
−
i
)
=
a
i
+
i
−
p
i
a_i-(p_i-i)=a_i+i-p_i
ai−(pi−i)=ai+i−pi
p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn是个排列
我把所有人按照 a i + i a_i+i ai+i排序,然后给最大的分配 p = n p=n p=n,次大的 p = n − 1 p=n-1 p=n−1
最后 c h e c k check check一下就好了
代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll n;
pll a[maxn];
int main()
{
ll i;
n=read();
rep(i,n)a[i].first=read(), a[i].second=i;
sort(a+1,a+n+1,[](pll x, pll y){return x.first+x.second < y.first+y.second;});
for(i=n-1;i;i--)if(a[i].first+a[i].second-i>a[i+1].first+a[i+1].second-(i+1))
{
printf(":(");
return 0;
}
for(i=1;i<=n;i++)
{
printf("%lld ",a[i].first+a[i].second-i);
}
return 0;
}