卧薪尝胆,厚积薄发。
Happy Line
Date: Thu Jul 19 18:51:00 CST 2018 In Category: NoCategory

Description:

给定一个长为 $n$ 的序列 $a_i$ ,你可以执行任意次操作,每次操作可以交换 两个相邻位置 $(i,i+ 1)$ 上的数,且交换后位置上的数变为 $(a_{i+1}+1,a_i−1)$ ,问是否能通过任意次操作使得 $a_i$ 不降,若有解则给出最终的 $a_i$ 。
$1\le n \le 2\times10^5$

Solution:

设 $x,y$ 被调到了 $u,v(u < v)$ ,则有 $a_x+(x-u)\le a_y+(y-v)$ ,即 $a_x+x\le a_y+y+(u-v)$ ,因为 $u<v$ ,所以 $a_x+x<a_y+y$ ,所以将所有数按 $a_i+i$ 排序就得到了最后的答案,然后模拟就行了。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXN 200010
int a[MAXN];
int s[MAXN];
bool cmp(int x,int y){return a[x] + x < a[y] + y;}
int b[MAXN];
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)scanf("%d",&a[i]);
for(int i = 1;i <= n;++i)s[i] = i;
sort(s + 1,s + 1 + n,cmp);
for(int i = 1;i <= n;++i)b[i] = a[s[i]] + s[i] - i;
bool found = true;
for(int i = 1;i < n;++i)if(b[i] > b[i + 1]){found = false;break;}
if(found)for(int i = 1;i <= n;++i)cout << b[i] << " ";
else cout << ":(";
cout << endl;
return 0;
}
In tag: 算法-排序
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡