Codeforces 729E Subordinates

时间:2023-03-09 00:38:56
Codeforces 729E Subordinates

题目链接:http://codeforces.com/problemset/problem/729/E


既然每一个人都有一个顶头上司,考虑一个问题:

  如果这些人中具有上司数目最多的人有$x$个上司,那么一定存在一些人,他们分别有$x-1,x-2...1$个上司。

首先如果$s$位置上的上司数目不为$0$,非$s$位置上的上司数目为$0$它们就是一定说错了话的。

问题转化为了:将合法的上司数目从小到大小排序,我们现在要这个序列的数字连续单调不降,并且相差不能为大于$1$。

有一人些已经说错了话,考虑用他们补足中间的差值的空隙,如果补不足再贪心的把最大的减小往前补。

注意如果最后一个人和前一个人差值有间隙,直接把它他减小即可。


 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 1001000
#define llg int
#define inf 0x7fffffff
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,la,a[maxn],ans,s;
bool bj[maxn];
int main()
{
yyj("Subordinates");
cin>>n>>s;
for (llg i=;i<=n;i++)
{
scanf("%d",&a[i]);
if (i==s)
{
if (a[i]!=) ans++;
a[i]=;
}
if (a[i]== && i!=s) a[i]=inf,ans++;
}
sort(a+,a+n+);
bj[]=; la=;
for (llg i=;i<=n;i++)
{
if (a[i]== || a[i]==inf) continue;
if (!bj[a[i]-])
{
if (a[n]!=inf) ans++;
bj[la]=; la=la+;
if (n!=i) i--;
n--;
continue;
}
bj[a[i]]=; la=a[i]+;
}
cout<<ans;
return ;
}