题目大意:
n个人,每个人对应一个能力值,接下来有m对互相不能“在一起”的人的编号。能力高的可以做能力低的人的老师,要求输出每个人最多有多少徒弟。
解题思路:
首先维护一个记录每个人可以拥有多少徒弟的数组,初始值为0。在输入不能在一起的人的时候,如果前者能力高于后者,那么前者徒弟就要-1,否则如果小于后者,那么后者徒弟数量-1。最后排序二分查找一次每个人第一次出现的位置即可(这里也可以用lower_bound()函数实现)。
代码如下:
#include<iostream>
#include<cstdio>
#include<fstream>
#include<set>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<iomanip>
#include<cstdlib>
#include<list>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
#define MOD 1000000007
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define meminf(a) memset(a,inf,sizeof(a))
#define HASHP 13331;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int a[200010],result[200010],b[200010];
int n,m;
int binary_search(int t)
{
int l=1,r=n+1;
int result=0;
while(l<r)
{
int mid=(l+r)/2;
if(a[mid]==t)
{
if(a[mid-1]<t)
{
result=mid;
break;
}
else r=mid;
}
else if(a[mid]>t)r=mid;
else l=mid+1;
}
return result;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
//freopen("test.txt","r",stdin);
//freopen("output.txt","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++){cin>>a[i];b[i]=a[i];}
while(m--)
{
int x,y;
cin>>x>>y;
if(a[x]>a[y])result[x]--;//徒弟-1的操作
if(a[x]<a[y])result[y]--;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
int temp=binary_search(b[i])-1;//比b[i]能力小的人数
// 也可以这样写 int temp=lower_bound(a+1,a+n+1,b[i])-a-1;
result[i]+=temp;
}
for(int i=1;i<=n;i++)cout<<result[i]<<' ';
cout<<endl;
return 0;
}