求帮忙分析时间复杂度
查看原帖
求帮忙分析时间复杂度
255169
__LePetitPrince__楼主2023/12/5 17:58

这是 P4447 [AHOI2018初中组] 分组 的代码:

#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int S = 1e5 + 5;
int n, a[S], n2;
vector<int> b;
int ans = S;
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", a + i);
	}
	sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++) {
		if (b.empty() || b.back() != a[i]) {
			b.push_back(a[i]);
		}
	}
	n2 = b.size();
	vector<int> c;
	int j = 1, cnt[S];
	for (int i = 0; i < n2; i++) {
		while (c.empty() || b[i] == c.back() + 1) {
			c.push_back(b[i]);
			i++;
		}
		int delta = a[j];
		int left = 0;
		for (auto p : c) {
			while (a[j] == p && j <= n) {
				cnt[a[j] - delta]++;
				j++;
				left++;
			}
		}
		int res = n, fst = 0;
		while (left > 0) {
			int l = 0;
			int idx = fst;
			while (true) {
				left--;
				l++;
				if (cnt[idx + 1] < cnt[idx]) {
					cnt[idx]--;
					break;
				}
				cnt[idx]--;
				idx++;
			}
			res = min(res, l);
			while (cnt[fst] == 0) {
				fst++;
			}
			if (fst >= c.size()) {
				break;
			}
		}
		ans = min(ans, res);
		for (int k = 0; k <= c.size(); k++) {
			cnt[k] = 0;
		}
		c.clear();
		i--;
//		cout << res << endl << endl;
	}
	cout << ans;
	return 0;
} 
/*
6
-1 -1 2 2 3 5
*/

虽然写的有点复杂但感觉 for (int i = 0; i < n2; i++) 这个循环的均摊复杂度是 O(n)\text{O(n)} 的,把 sort 算上时间复杂度应该是正确的 O(nlog⁡n)\text{O(n} \log \text{n)} 啊,但是最后的 hack 过不掉

Record: https://www.luogu.com.cn/record/138234647

感觉是 for (int i = 0; i < n2; i++) 这个循环的复杂度搞错了,求大佬们帮本蒟蒻看看 Orz

可能会十点多再回复不好意思 UwU

2023/12/5 17:58
加载中...