关于map的时间复杂度
查看原帖
关于map的时间复杂度
739515
wc3624762194楼主2025/2/4 17:28

以下代码,使用map超时了6个点https://www.luogu.com.cn/record/201257356

按照map插入和查找一个元素时间复杂度O(log N)算的话,整体代码时间复杂度是O(N^2 log N)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e4;
const ll MOD = 1e9 + 7;
ll a[N], b[N];
ll ap[N], bp[N];//哪个数字
int aq[N], bq[N]; //出现了几次
int suma, sumb;
map<ll, int>vo;
queue<ll>fin;
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	for (int i = 1; i <= n; i++)
		cin >> b[i];
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + n);
	//统计a,b中出现了多少个不一样的元素,并记录每个元素出现的次数(ap,bp,aq,bq记录)
	int len;
	for (int i = 1; i <= n; i++)
	{
		len = 1;
		while (a[i + 1] == a[i]) i++, len++;
		suma++, ap[suma] = a[i], aq[suma] = len;
	}
	for (int i = 1; i <= n; i++)
	{
		len = 1;
		while (b[i + 1] == b[i]) i++, len++;
		sumb++, bp[sumb] = b[i], bq[sumb] = len;
	}



	for (int i = 1; i <= suma; i++)
	{
		for (int j = 1; j <= sumb; j++)
		{
			ll mix = (ap[i] * bp[j]) % MOD;
			if (vo[mix] == 0) fin.push(mix);
			vo[mix] += min(aq[i], bq[j]);
		}
	}
	int ans = 0;
	while (!fin.empty())
	{
		ll x = fin.front();
		fin.pop();
		ans = max(ans, vo[x]);
	}
	cout << ans;
	return 0;
}

改后的代码仅把map中需要插入的元素全部存进了一个数组c,最后还用sort对数组c中元素进行了排序,按照sort对N*N个元素进行排序,整体复杂度为O(N^2 log (N^2) ),看时间复杂度的话还稍微慢了一点点。但是最大的一个测试点300ms以内就能通过 https://www.luogu.com.cn/record/201266560

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2005;
const int MOD = 1e9 + 7;
ll a[N], b[N];
ll ap[N], bp[N];//哪个数字
int aq[N], bq[N]; //出现了几次
int suma, sumb, sum, ans;
ll c[N * N];
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
		scanf("%lld", &a[i]);
	for (int i = 1; i <= n; i++)
		scanf("%lld", &b[i]);
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + n);
	//统计a,b中出现了多少个不一样的元素,并记录每个元素出现的次数(ap,bp,aq,bq记录)
	int len;
	for (int i = 1; i <= n; i++)
	{
		len = 1;
		while (a[i + 1] == a[i]) i++, len++;
		suma++, ap[suma] = a[i], aq[suma] = len;
	}
	for (int i = 1; i <= n; i++)
	{
		len = 1;
		while (b[i + 1] == b[i]) i++, len++;
		sumb++, bp[sumb] = b[i], bq[sumb] = len;
	}

  //该段往后较上段代码进行了修改
	for (int i = 1; i <= suma; i++)
	{
		for (int j = 1; j <= sumb; j++)
		{
			ll mix = (ap[i] * bp[j]) % MOD;
			int k = min(aq[i], bq[j]);
			while (k--) sum++, c[sum] = mix;
		}
	}
	sort(c + 1, c + 1 + sum);
	for (int i = 1; i <= sum; i++)
	{
		len = 1;
		while (c[i + 1] == c[i]) len++, i++;
		ans = max(ans, len);
	}
	cout << ans;
	return 0;
}

本蒟蒻交了十几遍代码,发现是第一段代码map插入元素那一行"vo[mix] += min(aq[i], bq[j]);"直接导致超时,猜测是否是因为map插入元素操作时间复杂度出现问题,望解答

2025/2/4 17:28
加载中...