题目链接:http://codeforces.com/problemset/problem/729/E
既然每一个人都有一个顶头上司,考虑一个问题:
如果这些人中具有上司数目最多的人有$x$个上司,那么一定存在一些人,他们分别有$x-1,x-2...1$个上司。
首先如果$s$位置上的上司数目不为$0$,非$s$位置上的上司数目为$0$它们就是一定说错了话的。
问题转化为了:将合法的上司数目从小到大小排序,我们现在要这个序列的数字连续单调不降,并且相差不能为大于$1$。
有一人些已经说错了话,考虑用他们补足中间的差值的空隙,如果补不足再贪心的把最大的减小往前补。
注意如果最后一个人和前一个人差值有间隙,直接把它他减小即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 1001000 10 #define llg int 11 #define inf 0x7fffffff 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,m,la,a[maxn],ans,s; 14 bool bj[maxn]; 15 int main() 16 { 17 yyj("Subordinates"); 18 cin>>n>>s; 19 for (llg i=1;i<=n;i++) 20 { 21 scanf("%d",&a[i]); 22 if (i==s) 23 { 24 if (a[i]!=0) ans++; 25 a[i]=0; 26 } 27 if (a[i]==0 && i!=s) a[i]=inf,ans++; 28 } 29 sort(a+1,a+n+1); 30 bj[0]=1; la=1; 31 for (llg i=1;i<=n;i++) 32 { 33 if (a[i]==0 || a[i]==inf) continue; 34 if (!bj[a[i]-1]) 35 { 36 if (a[n]!=inf) ans++; 37 bj[la]=1; la=la+1; 38 if (n!=i) i--; 39 n--; 40 continue; 41 } 42 bj[a[i]]=1; la=a[i]+1; 43 } 44 cout<<ans; 45 return 0; 46 }