QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#431109#8761. 另一个计数问题RepeaterWA 1ms3768kbC++202.3kb2024-06-04 22:53:032024-06-04 22:53:04

Judging History

你现在查看的是最新测评结果

  • [2024-06-04 22:53:04]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3768kb
  • [2024-06-04 22:53:03]
  • 提交

answer

#include <bits/stdc++.h>

using i64 = long long;
using i128 = __int128;

constexpr int p = 998244353;

std::vector<int> vis, primes;

void sieve(i64 n)
{
	vis.resize(n + 1);
	primes.clear();
	primes.emplace_back(0);

	for(int i = 2; i <= n; i++)
	{
		if(!vis[i]) primes.emplace_back(i);
		for(auto j : primes)
		{
			if(j == 0) continue;
			if(i * j > n) break;
			vis[i * j] = 1;
			if(i % j == 0) break;
		}
	}
}

auto Min_25(i64 n)
{
	int sqrt_n = std::sqrt(n) + 1;

	sieve(sqrt_n);

	int m = primes.size() - 1;
	std::vector sum(2, std::vector<i64>(m + 1));
	for(int i = 1; i <= m; i++)
	{
		sum[0][i] = (sum[0][i - 1] + 1LL * primes[i]) % p;
		sum[1][i] = (sum[1][i - 1] + 1LL * primes[i] * primes[i] % p) % p;
	}

	std::vector<i64> val;
	std::vector id(2, std::vector<int>(2 * sqrt_n + 1));
	std::vector g(2, std::vector<i64>(2 * sqrt_n + 1));

	for(i64 l = 1, r; l <= n; l = r + 1)
	{
		r = n / (n / l);
		val.emplace_back(n / l);

		int cur = val.size() - 1;
		if(n / l <= sqrt_n) id[0][n / l] = cur;
		else id[1][l] = cur;

		i128 t = (n / l) % p;
		g[0][cur] = (t * (t + 1) / 2 % p - 1 + p) % p;
		g[1][cur] = (t * (t + 1) * (2 * t + 1) / 6 % p - 1 + p) % p;
	}

	for(int x = 1; x <= m; x++)
	{
		i64 i = primes[x];
		for(int j = 0; j < val.size() && i * i <= val[j]; j++)
		{
			i64 t = val[j] / i;
			if(t <= sqrt_n) t = id[0][t];
			else t = id[1][n / t];

			g[0][j] = (g[0][j] - 1LL * i * (g[0][t] - sum[0][x - 1] + p) % p + p) % p;
			g[1][j] = (g[1][j] - 1LL * i * i % p * (g[1][t] - sum[1][x - 1] + p) % p + p) % p;

		}
	}

	return std::make_pair(g[0][id[1][1]], g[1][id[1][1]]);
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	i64 n; std::cin >> n;

	auto S1 = [&](i64 n) -> i64
	{	
		return i64(i128(n) * (n + 1) / 2 % p);
	};

	auto S2 = [&](i64 n) -> i64
	{	
		return i64(i128(n) * (n + 1) * (2 * n + 1) / 6 % p);
	};

	auto [s1, s2] = Min_25(n);
	auto [s11, s22] = Min_25((n + 1) / 2);
	s1 = (s1 - s11 + p) % p, s2 = (s2 - s22 + p) % p;

	i64 ans = ((S1(n) * S1(n) - S2(n) + p) % p * (p + 1) / 2 % p - S1(n) + 1 + p) % p;
	ans = (ans - 1LL * s1 * (S1(n) - s1 - 1 + p) % p - (1LL * s1 * s1 - s2 + p) % p * (p + 1) / 2 % p + p + p) % p;

	std::cout << ans << "\n";

	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3768kb

input:

4

output:

8

result:

ok 1 number(s): "8"

Test #2:

score: -100
Wrong Answer
time: 1ms
memory: 3768kb

input:

5

output:

26

result:

wrong answer 1st numbers differ - expected: '8', found: '26'