CF978F 题解

题目传送门。

本题是一道双数组好题。

论什么是双数组?

在一些题目当中,虽然只输入一个数组,但是一个数组是满足不了我们的需要的,所以我们需要两个数组,例如本题。

论如何使用双数组?

方法一:在输入时拷贝,例:

for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}

方法二:在想要使用时拷贝,例:

for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		c[i]=a[i];
	}

那么本题和双数组有什么关系?

要明确这点,首先我们要明确本题的思路。

很明显,假设没有冲突,则每个人可以成为所有能力值比他小的人的导师。

这个可以使用

sort(a+1,a+n+1);//排序
	for(int i=1;i<=n;i++){
		int p=lower_bound(a+1,a+n+1,a[i])-a;//找到第一个比b[i]小的数的下标,则这个数减一就是初始答案
		ans[i]=p-1;
	}

来解决。

但如果加入了冲突,那么一定会出现这种:

for(int i=1;i<=k;i++){
		cin>>x>>y;
		if(a[x]<a[y])ans[y]--;
		if(a[y]<a[x])ans[x]--;
	}

aa 是已经排过序的数组,这么计算一定不准确。

那么我们可以拷贝一个 bb 数组,代码如下:

for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		int p=lower_bound(a+1,a+n+1,b[i])-a;
		ans[i]=p-1;
	}
	for(int i=1;i<=k;i++){
		cin>>x>>y;
		if(b[x]<b[y])ans[y]--;
		if(b[y]<b[x])ans[x]--;
	}

这样 bb 数组未经排序,一定可以统计答案。

本题有没有单数组解法?

翻遍了题解区(AC\color{green}\operatorname{AC} 之后),无。

本题的时间复杂度

O(n)\operatorname{O}(n)

全代码

#include<bits/stdc++.h>
using namespace std;
int a[200001],b[200001];
int ans[200001],x,y;
int n,k;
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		int p=lower_bound(a+1,a+n+1,b[i])-a;
		ans[i]=p-1;
	}
	for(int i=1;i<=k;i++){
		cin>>x>>y;
		if(b[x]<b[y])ans[y]--;
		if(b[y]<b[x])ans[x]--;
	}
	for(int i=1;i<=n;i++){
		cout<<ans[i]<<' ';
	}
	return 0;
}
posted @   Weslie_qwq  阅读(1)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示