QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#650596#8327. 积性函数求和 $10^{13}$ 方便 FFT 版zydyWA 0ms3712kbC++1711.6kb2024-10-18 15:45:512024-10-18 15:45:52

Judging History

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

  • [2024-10-18 15:45:52]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3712kb
  • [2024-10-18 15:45:51]
  • 提交

answer

#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <time.h>
#include <fstream>
using namespace std;
using u32 = unsigned int;
using u64 = unsigned long long;
using i64 = long long;
constexpr u32 mod = 469762049;
inline constexpr u32 norm(const u32 x) { return x < mod ? x : x - mod; }
struct m32 {
	u32 x;
	m32() { }
	constexpr m32(const u32 _x) : x(_x) { }
};
inline constexpr m32 operator + (const m32 x1, const m32 x2) { return norm(x1.x + x2.x); }
inline constexpr m32 operator - (const m32 x1, const m32 x2) { return norm(x1.x + mod - x2.x); }
inline constexpr m32 operator - (const m32 x) { return x.x ? mod - x.x : 0; }
inline constexpr m32 operator * (const m32 x1, const m32 x2) { return static_cast<u64>(x1.x) * x2.x % mod; }
inline m32& operator += (m32& x1, const m32 x2) { return x1 = x1 + x2; }
inline m32& operator -= (m32& x1, const m32 x2) { return x1 = x1 - x2; }
inline m32& operator *= (m32& x1, const m32 x2) { return x1 = x1 * x2; }
inline bool operator == (const m32 x1, const m32 x2) { return x1.x == x2.x; }
inline bool operator != (const m32 x1, const m32 x2) { return x1.x != x2.x; }

struct block {
	static int v;
	vector<m32> sv;
	vector<m32> lv;
	block() : sv(v + 1, 0), lv(v + 1, 0) {}
};
int block::v;

inline void add(m32& x, const u32 a, const u32 b) { x = (x.x + 1ULL * a * b) % mod; }
inline void add(m32& x, const m32 a, const m32 b) { add(x, a.x, b.x); }
inline void sub(m32& x, const m32 a, const m32 b) { add(x, a.x, mod - b.x); }

block solve(const i64 N, m32 A, m32 B) {
	const int v = sqrt(N + 0.5);
	const int n_4 = sqrt(v + 0.5);
	const int n_8 = sqrt(n_4 + 0.5);
	block::v = v;

	vector<int> primes;
	vector<int> pi(v + 1);
	vector<bool> is_prime(v + 1);
	primes.push_back(1);
	is_prime[2] = true;
	for (int i = 3; i <= v; i += 2) is_prime[i] = true;
	for (int i = 3; i * i <= v; i += 2)
		for (int j = i * i; is_prime[i] && j <= v; j += (i << 1))
			is_prime[j] = false;
	for (int i = 2; i <= v; ++i) {
		pi[i] = pi[i - 1] + is_prime[i];
		if (is_prime[i]) primes.push_back(i);
	}

	vector<m32> sup;
	sup.resize(primes.size());
	u32 rec[4];
	rec[1] = 1;
	for (int i = 2; i <= 3; ++i)
		rec[i] = (i64)(mod - mod / i) * rec[mod % i] % mod;
	m32 inv3 = m32(rec[3]);

	const auto divide = [](i64 n, i64 d) -> i64 {return double(n) / d; };
	const auto divide_32 = [](i64 n, int d) -> int {return double(n) / d; };

	auto calc_medium = [&](const function<m32(u64)>& fp) {
		sup.clear();
		sup[0] = m32(0);
		for (int i = 1; i <= pi[v]; ++i) sup[i] = fp(primes[i]);

		vector<m32> lq(v + 1, 0);
		for (int i = 1; i <= pi[v]; ++i) lq[primes[i]] += sup[i];
		for (int i = 1; i <= v; ++i) lq[i] += lq[i - 1];

		block f;
		const i64 K1 = max<i64>(min((i64)pow(N, 2.0 / 3) * 4, N), v + 1);
		const int _v = sqrt(K1), B1 = N / K1;
		for (int i = pi[n_4] + 1; i <= pi[_v]; ++i) {
			const i64 M = N / primes[i];
			const int t = pi[min(divide_32(K1, primes[i]), v)];
			for (int j = i; j <= t; ++j) f.lv[divide_32(M, primes[j])] += sup[i] * sup[j];
		}
		for (int i = v - 1; i > B1; --i) f.lv[i] += f.lv[i + 1];
		for (int k = 1; k <= B1; ++k) {
			f.lv[k] = m32(0);
			const i64 M = N / k;
			const int t1 = pi[sqrt(M + 0.5)], t0 = pi[v / k];
			int j = pi[n_4] + 1;
			for (; j <= t0; ++j) f.lv[k] += sup[j] * (lq[v] - lq[primes[j - 1]]);
			for (; j <= t1; ++j) f.lv[k] += sup[j] * (lq[divide_32(M, primes[j])] - lq[primes[j - 1]]);
		}
		for (int k = 1; k <= n_4; ++k) {
			int t = v / k;
			i64 m = N / k;
			m32 ans = m32(0);
			for (int i = pi[n_4] + 1; i <= pi[t]; ++i) ans += sup[i] * f.lv[primes[i] * k];
			for (int i = pi[n_4] + 1; i <= pi[t]; ++i) {
				i64 q = (i64)primes[i] * primes[i];
				if (q * n_4 > m) break;
				ans += sup[i] * sup[i] * (lq[divide(m, q)] - lq[n_4]);
			}
			t = cbrt(m + 0.5);
			for (int i = pi[n_4] + 1; i <= pi[t]; ++i) ans += sup[i] * sup[i] * sup[i];
			f.lv[k] += ans * inv3;
		}
		for (int i = 1; i <= v; ++i) f.lv[i] += lq[v] - lq[n_4] + 1;
		for (int i = 1; i <= n_4; ++i) f.sv[i] = 1;
		for (int i = n_4 + 1; i <= v; ++i) f.sv[i] = lq[i] - lq[n_4] + 1;
		for (int i = 0; i <= v; ++i) lq[i] = 0;

		vector<m32> sq(v + 1, 0);
		int mm = v * max(log(N) / 10, 1.);
		int K = min(N, (i64)(mm * pow(N, 0.125))), B = N / K;
		m32 sum_s = 0;
		const auto add_s = [&](int x, m32 cnt) -> void {
			sum_s += cnt;
			while (x <= v) sq[x] += cnt, x += x & -x;
			};
		const auto add_l = [&](int x, m32 cnt) -> void {
			x = v + 1 - x;
			while (x <= v) lq[x] += cnt, x += x & -x;
			};
		function <void(int, int, m32)> dfs = [&](int n, int id, m32 fn) {
			if (n <= v) add_s(n, fn);
			else add_l(divide_32(N, n), fn);
			for (int i = id; i <= pi[v]; ++i) {
				i64 q = (i64)n * primes[i];
				if (q > K) break;
				dfs(q, i, fn * sup[i]);
			}
			};
		auto query_s = [&](int x) -> m32 {
			m32 ans = f.sv[x];
			while (x) ans += sq[x], x ^= x & -x;
			return ans;
			};
		auto query_l = [&](int x) -> m32 {
			x = v + 1 - x;
			m32 ans = sum_s;
			while (x) ans += lq[x], x ^= x & -x;
			return ans;
			};
		int K2, B2;
		for (int id = pi[n_4]; id > pi[n_8]; --id) {
			const int p = primes[id];
			const u64 m = N / p;
			dfs(p, id, sup[id]);
			const int t0 = B / p, t1 = min(B, v / p);
			for (int i = B; i > t1; --i) add(f.lv[i], sup[id], query_s(divide_32(m, i)));
			for (int i = t1; i > t0; --i) add(f.lv[i], sup[id], f.lv[i * p] + query_l(i * p));
			for (int i = t0; i; --i) add(f.lv[i], sup[id], f.lv[i * p]);
			K2 = mm * sqrt(p);
			B2 = N / K2;
			for (int i = B2; i > B; --i) f.lv[i] += query_l(i);
			K = K2, B = B2;
		}
		for (int i = B + 1; i <= v; ++i) f.lv[i] += query_l(i);
		for (int i = 1; i <= v; ++i)
			if (i & (i - 1))
				sq[i] += sq[i & (i - 1)];
		for (int i = 1; i <= v; ++i) f.sv[i] += sq[i];
		return f;
		};

	auto attach_small = [&](block&& f, const function<m32(u64)>& fp) {
		for (int id = pi[n_8]; id; --id) {
			const int p = primes[id], t = v / p;
			const i64 m = N / p;
			for (int j = 1, i = p; j <= t; ++j) {
				const m32 c1 = sup[id] * f.sv[j];
				for (int e = min(v + 1, i + p); i < e; ++i) f.sv[i] += c1;
			}
			for (int i = v; i > t; --i) add(f.lv[i], sup[id], f.sv[divide_32(m, i)]);
			for (int i = t; i >= 1; --i) add(f.lv[i], sup[id], f.lv[i * p]);
		}
		return move(f);
		};

	auto calc_large = [&](const function<m32(u64)>& fp, const function<m32(u64)>& sum_fp) {
		block f = attach_small(calc_medium(fp), fp);
		block res;
		for (int i = v; i >= 1; --i) {
			m32 ans = sum_fp(N / i) - f.lv[i];
			for (int j = 2; i * j <= v; ++j) sub(ans, fp(j), res.lv[i * j]);
			res.lv[i] = ans;
		}
		return res;
		};

	auto mult_large = [&](block&& f, const block& l) {
		for (int i = 1; i <= v; ++i) {
			for (int j = 1; i * j <= v; ++j)
				if (f.sv[j] != f.sv[j - 1])
					add(f.lv[i], f.sv[j] - f.sv[j - 1], l.lv[i * j]);
		}
		return move(f);
		};

	auto mult_powerful = [&](block&& f, const function<m32(u32, u32)>& fpp) {
		m32 s_sum = f.sv[v];
		for (int i = v; i >= 1; --i) {
			if (i & (i - 1)) f.lv[v + 1 - i] -= f.lv[v + 1 - (i & (i - 1))];
			else f.lv[v + 1 - i] -= s_sum;
		}
		for (int i = v; i >= 1; --i)
			if (i & (i - 1)) f.sv[i] -= f.sv[i & (i - 1)];

		const auto sum_s = [&](int i, int j) -> m32 {
			const int m = i & (~u64(0) << (64 - __builtin_clzll(i ^ j)));
			m32 ret = m32(0);
			while (i > m) ret -= f.sv[i], i &= i - 1;
			while (j > m) ret += f.sv[j], j &= j - 1;
			return ret;
			};
		const auto sum_l = [&](int i, int j) -> m32 {
			i = v + 1 - i;
			j = v + 1 - j;
			const int m = i & (~u64(0) << (64 - __builtin_clzll(i ^ j)));
			m32 ret = m32(0);
			while (i > m) ret -= f.lv[v + 1 - i], i &= i - 1;
			while (j > m) ret += f.lv[v + 1 - j], j &= j - 1;
			return ret;
			};
		const auto common = [&](int i, int j) -> int {
			const int mask = (~u64(0) >> 1) >> __builtin_clzll(i ^ j);
			const int m = (i & mask) == 0 ? (i + (i & -i)) : (j & mask) != 0 ? ((j & ~mask) + mask + 1) : j;
			return (m > v) ? v : m;
			};
		const auto add_s_fix = [&](int i, int m) -> void {
			for (int k = i + (i & -i); k <= m; i = k, k += k & -k) f.sv[k] += f.sv[i];
			};
		const auto add_s = [&](int i, int j, m32 s) -> void {
			const int m = common(i, j);
			add_s_fix(j, m);
			m32 t = f.sv[i];
			f.sv[i] = t + s;
			for (i += i & -i; i <= m; i += i & -i) f.sv[i] -= t, t += f.sv[i];
			};
		const auto add_l_fix = [&](int i, int m) -> void {
			for (int k = i + (i & -i); k <= m; i = k, k += k & -k) f.lv[v + 1 - k] += f.lv[v + 1 - i];
			};
		const auto add_l = [&](int i, int j, m32 s) -> void {
			i = v + 1 - i;
			j = v + 1 - j;
			const int m = common(i, j);
			add_l_fix(j, m);
			m32 t = f.lv[v + 1 - i];
			f.lv[v + 1 - i] = t + s;
			for (i += i & -i; i <= m; i += i & -i)
				f.lv[v + 1 - i] -= t, t += f.lv[v + 1 - i];
			};
		const auto add_l2 = [&](int i, m32 s) -> void {
			int t = v + 1 - i, nt = t + (t & -t);
			if (nt <= v) f.lv[v + 1 - nt] -= f.lv[i];
			f.lv[i] += s;
			};
		const auto add_l2_fix = [&](int i) -> void {
			for (int t = v + 1 - i; t <= v; ++t)
				if (t + (t & -t) <= v) {
					f.lv[v + 1 - (t + (t & -t))] += f.lv[v + 1 - t];
				}
			};

		m32 fs[65] = { 1 };
		for (int i = 1; i <= pi[v]; ++i) {
			const int p = primes[i];
			i64 e_max = 1;
			fs[1] = fpp(p, 1);
			for (i64 M = divide(N, p); M >= p; M = divide(M, p), ++e_max) fs[e_max + 1] = fs[e_max] * fs[1];
			i64 q = i64(p) * p;
			for (i64 e = 2; e <= e_max; ++e, q *= p) {
				const m32 d = fpp(p, e) - fs[e];
				if (d == 0) continue;
				for (i64 e2 = e_max; e2 >= e; --e2) fs[e2] += fs[e2 - e] * d;
				const i64 L = N / q;
				const int th_l = sqrt(L + 0.5), th_s = divide(L, th_l + 1);
				int pq = divide(L, v / q + 1);
				if (q <= v) {
					for (int j = 1; j <= v / q; ++j) {
						const i64 k = i64(j + 1) * q;
						const m32 s = (k <= v) ? sum_l(k, j * q) : (sum_l(v + 1, j * q) + sum_s(pq, v));
						add_l2(j, d * s);
					}
				}
				for (int j = v / q + 1, nq = 0; j <= th_l; ++j, pq = nq)
					add_l2(j, d * sum_s(nq = divide(L, j + 1), pq));
				add_l2_fix(th_l);
				int pq2 = 0, pk = v + 1;
				for (int j = th_s, nq2 = 0; j >= 1; --j) {
					const i64 k = i64(j) * q;
					const m32 s = sum_s(j - 1, j);
					if (k <= v) add_s(k, pk, d * s), pk = k;
					else add_l(nq2 = divide(N, k), pq2, d * s), pq2 = nq2;
				}
				if (q <= v) add_s_fix(q, v);
				if (pq2 > 0) add_l_fix(v + 1 - pq2, v);
			}
		}
		for (int i = 1; i <= v; ++i)
			if (i & (i - 1))
				f.sv[i] += f.sv[i & (i - 1)];
		s_sum = f.sv[v];
		for (int i = 1; i <= v; ++i) {
			if (i & (i - 1)) f.lv[v + 1 - i] += f.lv[v + 1 - (i & (i - 1))];
			else f.lv[v + 1 - i] += s_sum;
		}
		return f;
		};

	block l0 = calc_large([&](u64 n) { return 1; }, [&](u64 n) { return m32(n % mod); });
	block l1 = calc_large([&](u64 n) { return m32(n % mod); }, [&](u64 n) { return n %= mod, m32(n * (n + 1) / 2 % mod); });
	for (int i = 1; i <= v; ++i) l1.lv[i] = A * l0.lv[i] + B * l1.lv[i], l1.sv[i] = 0;

	auto fp = [&](u32 p) { return A + B * p; };
	auto fpp = [&](u32 p, u32 e) { return A * e + B * p; };
	return mult_powerful(attach_small(mult_large(calc_medium(fp), l1), fp), fpp);
}
signed main() {
	i64 T, n;
	m32 A, B;
	while (T--) {
		cin >> n >> A.x >> B.x;
		block f = solve(n, A, B);
		vector<m32> res(f.sv.begin() + 1, f.sv.end());
		res.insert(res.end(), f.lv.begin() + 1, f.lv.end());
		sort(res.begin(), res.end(), [](const m32 a, const m32 b) { return a.x < b.x; });
		res.erase(unique(res.begin(), res.end()), res.end());
		u32 ans = 0;
		for (auto x : res) ans ^= x.x;
		cout << ans << endl;
	}
	return 0;
}

詳細信息

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3712kb

input:

10000
988 56395756 60780067
7923 293552717 438195956
4847 24236686 75287211
6694 74889751 64994726
3720 385482711 188638093
6021 2928896 248853035
6808 310612405 330739724
4062 15289930 175596707
9583 56394035 335888448
9798 151396947 371306315
4365 216662501 351771943
1359 165179730 80942360
1436 3...

output:


result:

wrong answer Answer contains longer sequence [length = 10000], but output contains 0 elements