社区讨论

这个为啥 tle 了呢?

CF1822G2Magic Triples (Hard Version)参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo1xj8a3
此快照首次捕获于
2023/10/23 04:36
2 年前
此快照最后确认于
2023/11/03 05:03
2 年前
查看原帖
常规思路,数据分治。a[i] <= 1e6 就枚举其约数,a[i] >= 1e6 就枚举一个 d 满足 a[i] * d <= MAXV。理论上说两种枚举复杂度都是 O(V13V^ {\frac 13})级别的,V <= 1e9,不知道是不是被卡常了(已经尽力卡常了)。
CPP
#pragma GCC optimize(2)
#include <cctype>
#include <iostream>
#include <unordered_map>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

int read()
{
	int s = 0;
	char ch = getchar();
	while (!isdigit(ch)) ch = getchar();
	while (isdigit(ch)) s = s * 10 + ch - '0', ch = getchar();
	return s;
}

int main()
{
	auto solve = [&]()
	{
		int n = read();
		const int N = 2e5 + 10;
		static int a[N];
		static unordered_map<int, int> cnt;
		cnt.clear();
		LL ans = 0;
		int L = 0;
		for (int i = 1; i <= n; ++i)
		{
			a[i] = read();
			++ cnt[a[i]];
			L = max(L, a[i]);
		}
		const int MAX = 1e9, MAX1 = 1e3, MAX2 = 1e6;
		for (int i = 1; i <= n; ++i)
		{
			int x = a[i];
			if (x >= MAX2)
				for (int d = 2; (LL)x * d <= L; ++d)
				{
					if (x % d == 0)
						ans += (LL)cnt[x / d] * cnt[x * d];
				}
			else
				for (int d = 1; d <= x / d; ++d)
					if (x % d == 0)
					{
						int t = x / d;
						if (d != x && (LL)x * t <= MAX) ans += (LL)cnt[d] * cnt[x * t];
						if (d != t && t != x && (LL)x * d <= MAX) ans += (LL)cnt[t] * cnt[x * d];
					}
		}

		for (auto [v, tot] : cnt)
			ans += (LL)tot * (tot - 1) * (tot - 2);

		printf("%lld\n", ans);
		
		return 0;
	};

	int T = read();
	while (T --)
		solve();
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...