QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#770266#8327. 积性函数求和 $10^{13}$ 方便 FFT 版I_be_wannaAC ✓5854ms187136kbC++2028.1kb2024-11-21 21:18:302024-11-21 21:18:31

Judging History

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

  • [2024-11-21 21:18:31]
  • 评测
  • 测评结果:AC
  • 用时:5854ms
  • 内存:187136kb
  • [2024-11-21 21:18:30]
  • 提交

answer

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <functional>
#include <vector>

typedef unsigned int uint;
typedef long long unsigned int uint64;

inline uint _udiv64(uint64 u, uint v)
{
	uint u0 = u, u1 = u >> 32;
	uint q, r;
	__asm__("divl %[v]" : "=a"(q), "=d"(r) : [v] "r"(v), "a"(u0), "d"(u1));
	return q;
}

constexpr uint Mod = 469762049;

inline constexpr uint norm(const uint x)
{
	return x < Mod ? x : x - Mod;
}

struct Z
{
	uint v;
	Z() { }
	constexpr Z(const uint _v) : v(_v) { }
};

inline constexpr Z operator+(const Z x1, const Z x2) { return norm(x1.v + x2.v); }
inline constexpr Z operator-(const Z x1, const Z x2) { return norm(x1.v + Mod - x2.v); }
inline constexpr Z operator-(const Z x) { return x.v ? Mod - x.v : 0; }
inline constexpr Z operator*(const Z x1, const Z x2) { return static_cast<uint64>(x1.v) * x2.v % Mod; }
inline Z &operator+=(Z &x1, const Z x2) { return x1 = x1 + x2; }
inline Z &operator-=(Z &x1, const Z x2) { return x1 = x1 - x2; }
inline Z &operator*=(Z &x1, const Z x2) { return x1 = x1 * x2; }
inline bool operator==(const Z x1, const Z x2) { return x1.v == x2.v; }
inline bool operator!=(const Z x1, const Z x2) { return x1.v != x2.v; }

struct DS
{
	static uint64 N;
	static int R2;
	
	std::vector<Z> sv;
	std::vector<Z> lv;
	
	DS() : sv(1 + R2, 0), lv(1 + R2, 0) { }
	
	Z &operator[](const uint64 x)
	{
		return x <= R2 ? sv[x] : lv[N / x];
	}
	
	const Z &operator[](const uint64 x) const
	{
		return x <= R2 ? sv[x] : lv[N / x];
	}
	
	void partial_sum()
	{
		for (int i = 2; i <= R2; ++i)
			sv[i] += sv[i - 1];
		lv[R2] += sv[R2];
		for (int i = R2 - 1; i >= 1; --i)
			lv[i] += lv[i + 1];
	}
	
	void adjacent_difference()
	{
		for (int i = 1; i != R2; ++i)
			lv[i] -= lv[i + 1];
		lv[R2] -= sv[R2];
		for (int i = R2; i >= 2; --i)
			sv[i] -= sv[i - 1];
	}
};
uint64 DS::N;
int DS::R2;

inline void add(Z &x, const uint a, const uint b)
{
	x = (x.v + 1ULL * a * b) % Mod;
}
inline void add(Z &x, const Z a, const uint b) { add(x, a.v, b); }
inline void add(Z &x, const Z a, const Z b) { add(x, a.v, b.v); }
inline void sub(Z &x, const Z a, const Z b) { add(x, a.v, Mod - b.v); }

template<typename I>
struct subrange
{
	I i, s;
	
	subrange(I _i, I _s) : i(_i), s(_s) { }
	
	const I &begin() const { return i; }
	const I &end() const { return s; }
	bool empty() const { return i == s; }
	auto size() const { return s - i; }
};

DS operator*(const DS &a, const DS &b)
{
	const uint64 &N = DS::N;
	const int &R2 = DS::R2;
	
	DS res;
	
	auto s1 = [](const DS &ds) -> std::vector<std::pair<int, Z>>
	{
		std::vector<std::pair<int, Z>> vec;
		for (int i = 1; i <= R2; ++i)
			if (ds.sv[i] != ds.sv[i - 1])
				vec.emplace_back(i, ds.sv[i] - ds.sv[i - 1]);
		vec.emplace_back(R2 + 1, 0);
		return vec;
	};
	
	auto s2 = [&res](const int x, const Z y, const std::vector<std::pair<int, Z>> &p, const int l, const int r)
	{
		int i = l;
		for (const int X = R2 / x; i != r && p[i].first <= X; ++i)
			add(res.sv[x * p[i].first], y, p[i].second);
		for (const uint64 Nx = N / x; i != r; ++i)
			add(res.lv[_udiv64(Nx, p[i].first)], y, p[i].second);
	};
	
	auto s3 = [&res](const int x, const Z y, int i, const DS &ds)
	{
		const uint64 Nx = N / x;
		for (int X = R2 / x; i > X; --i)
			add(res.lv[i], y, ds.sv[_udiv64(Nx, i)]);
		for (; i >= 1; --i)
			add(res.lv[i], y, ds.lv[x * i]);
	};
	
	if (&a == &b)
	{
		const auto pa = s1(a);
		// const auto va = std::ranges::subrange(pa.begin(), pa.end() - 1);
		const auto va = subrange(pa.begin(), pa.end() - 1);
		
		for (int l = 0, r = va.size(); const auto &[x, y] : va)
		{
			++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pa[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			add(res[1ULL * x * x], y, y);
			s2(x, y * 2, pa, l, r);
			if (r)
				sub(res[1ULL * x * pa[r].first], y, a.sv[pa[r - 1].first] * 2);
		}
		
		res.partial_sum();
		
		for (int l = 0, r = va.size(); const auto &[x, y] : va)
		{
			++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pa[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			s3(x, y * 2, _udiv64(Nx, pa[r].first), a);
		}
	}
	else
	{
		const auto pa = s1(a);
		// const auto va = std::ranges::subrange(pa.begin(), pa.end() - 1);
		const auto va = subrange(pa.begin(), pa.end() - 1);
		const auto pb = s1(b);
		// const auto vb = std::ranges::subrange(pb.begin(), pb.end() - 1);
		const auto vb = subrange(pb.begin(), pb.end() - 1);
		
		for (int i = 1; i <= R2; ++i)
			add(res[1ULL * i * i], a.sv[i] - a.sv[i - 1], b.sv[i] - b.sv[i - 1]);
		
		for (int l = 0, r = vb.size(); const auto &[x, y] : va)
		{
			while (pb[l].first <= x)
				++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pb[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			s2(x, y, pb, l, r);
			if (r)
				sub(res[1ULL * x * pb[r].first], y, b.sv[pb[r - 1].first]);
		}
		for (int l = 0, r = va.size(); const auto &[x, y] : vb)
		{
			while (pa[l].first <= x)
				++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pa[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			s2(x, y, pa, l, r);
			if (r)
				sub(res[1ULL * x * pa[r].first], y, a.sv[pa[r - 1].first]);
		}
		
		res.partial_sum();
		
		for (int l = 0, r = vb.size(); const auto &[x, y] : va)
		{
			while (pb[l].first <= x)
				++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pb[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			s3(x, y, _udiv64(Nx, pb[r].first), b);
		}
		
		for (int l = 0, r = va.size(); const auto &[x, y] : vb)
		{
			while (pa[l].first <= x)
				++l;
			const uint64 Nx = N / x;
			while (r > l && Nx / pa[r - 1].first < r - 1)
				--r;
			if (r < l)
				r = l;
			s3(x, y, _udiv64(Nx, pa[r].first), a);
		}
	}
	
	return res;
}

DS mult_sparse(const DS &a, const DS &b)
{
	const uint64 &N = DS::N;
	const int &R2 = DS::R2;
	
	DS res;
	
	auto s1 = [](const DS &ds) -> std::vector<std::pair<int, Z>>
	{
		std::vector<std::pair<int, Z>> vec;
		for (int i = 1; i <= R2; ++i)
			if (ds.sv[i] != ds.sv[i - 1])
				vec.emplace_back(i, ds.sv[i] - ds.sv[i - 1]);
		vec.emplace_back(R2 + 1, 0);
		return vec;
	};
	
	auto s2 = [&res](const int x, const Z y, const std::vector<std::pair<int, Z>> &p, const int r)
	{
		int i = 0;
		for (const int X = R2 / x; i != r && p[i].first <= X; ++i)
			add(res.sv[x * p[i].first], y, p[i].second);
		for (const uint64 Nx = N / x; i != r; ++i)
			add(res.lv[_udiv64(Nx, p[i].first)], y, p[i].second);
	};
	
	auto s3 = [&res](const int x, const Z y, int i, const DS &ds)
	{
		const uint64 Nx = N / x;
		for (int X = R2 / x; i > X; --i)
			add(res.lv[i], y, ds.sv[_udiv64(Nx, i)]);
		for (; i >= 1; --i)
			add(res.lv[i], y, ds.lv[x * i]);
	};

	const auto pa = s1(a);
	// const auto va = std::ranges::subrange(pa.begin(), pa.end() - 1);
	const auto va = subrange(pa.begin(), pa.end() - 1);
	const auto pb = s1(b);
	// const auto vb = std::ranges::subrange(pb.begin(), pb.end() - 1);
	const auto vb = subrange(pb.begin(), pb.end() - 1);
	
	for (int l = 0, r = va.size(); const auto &[x, y] : vb)
	{
		const uint64 Nx = N / x;
		while (r && Nx / pa[r - 1].first < r - 1)
			--r;
		s2(x, y, pa, r);
		if (r)
			sub(res[1ULL * x * pa[r].first], y, a.sv[pa[r - 1].first]);
	}
	for (const auto &[x, y] : va)
	{
		sub(res.lv[_udiv64(R2, x)], y, b.sv[R2]);
	}
	
	res.partial_sum();
	
	for (int l = 0, r = va.size(); const auto &[x, y] : vb)
	{
		const uint64 Nx = N / x;
		while (r && Nx / pa[r - 1].first < r - 1)
			--r;
		s3(x, y, _udiv64(Nx, pa[r].first), a);
	}
	for (const auto &[x, y] : va)
	{
		for (int j = 1; x * j <= R2; ++j)
			add(res.lv[j], y, b.lv[x * j]);
	}
	
	return res;
}

DS calc(const uint64 N, const Z A, const Z B)
{
	DS::N = N;
	const int R2 = std::sqrt(N + 0.5);
	DS::R2 = R2;
	if (N == 0)
		return DS();
	if (N == 1)
	{
		DS ds;
		ds.sv[1] = ds.lv[1] = 1;
		return ds;
	}
	
	Z _Rec[65];
	_Rec[1] = 1;
	for (int i = 2; i <= 64; ++i)
		_Rec[i] = (Mod - Mod / i) * _Rec[Mod % i];
	
	const int R4 = std::sqrt(R2 + 0.5);
	const int R6 = std::cbrt(R2 + 0.5);
	
	std::vector<char> pf(1 + R2);
	std::vector<int> P;
	int L = -1;
	
	for (int p = 2; p <= R2; ++p)
		if (!pf[p])
		{
			if (L == -1 && p > R6)
				L = P.size();
			if (p <= R4)
				for (int j = p * p; j <= R2; j += p)
					pf[j] = 1;
			P.push_back(p);
		}
	if (L == -1)
		L = P.size();
	
	auto attach_powerful = [&](DS &ds, const std::function<Z (uint64, uint, uint)> &f) -> DS & // `ds` is the `DS` of `f` without powerful
	{
		DS powerful;
		auto gen = [&](int i, const uint64 x, const Z y)
		{
			auto gen_rec = [&](const auto &self, int i, const uint64 x, const Z y) -> void
			{
				powerful[x] += y;
				for (; i != P.size() && 1ULL * P[i] * P[i] <= N / x; ++i)
				{
					const uint64 Nx = N / x;
					const int p = P[i];
					const Z fp = f(p, p, 1);
					// assert(fp == ds.sv[p] - ds.sv[p - 1]);
					uint64 pe = 1ULL * p * p;
					Z fpe = 0;
					for (int e = 2; pe <= Nx; pe *= p, ++e)
					{
						fpe = f(pe, p, e) - fpe * fp;
						if (fpe.v)
							self(self, i + 1, x * pe, y * fpe);
					}
				}
			};
			return gen_rec(gen_rec, i, x, y);
		};
		gen(0, 1, 1);
		powerful.partial_sum();
		return ds = mult_sparse(ds, powerful);
	};
	
	auto fix_powerful = [&](DS &ds, const std::function<Z (uint64, uint, uint)> &f, const std::function<Z (uint64, uint, uint)> &now) -> DS &
	{
		DS powerful;
		auto gen = [&](int i, const uint64 x, const Z y)
		{
			auto gen_rec = [&](const auto &self, int i, const uint64 x, const Z y) -> void
			{
				powerful[x] += y;
				for (; i != P.size() && 1ULL * P[i] * P[i] <= N / x; ++i)
				{
					const uint64 Nx = N / x;
					const int p = P[i];
					Z fp[55] = {1, 0};
					Z nowp[55] = {1, now(p, p, 1)};
					// assert(f(p, p, 1) == ds.sv[p] - ds.sv[p - 1]);
					// assert(f(p, p, 1) == nowp[1]);
					uint64 pe = 1ULL * p * p;
					for (int e = 2; pe <= Nx; pe *= p, ++e)
					{
						fp[e] = f(pe, p, e);
						nowp[e] = now(pe, p, e);
						for (int ee = 0; ee < e; ++ee)
							fp[e] -= fp[ee] * nowp[e - ee];
						if (fp[e].v)
							self(self, i + 1, x * pe, y * fp[e]);
					}
				}
			};
			return gen_rec(gen_rec, i, x, y);
		};
		gen(0, 1, 1);
		powerful.partial_sum();
		return ds = mult_sparse(ds, powerful);
	};
	
	auto mult_powerful = [&](const DS &ds, const std::function<Z (uint64, uint, uint)> &f) // `ds` is the `DS` of another function
	{
		DS powerful;
		auto gen = [&](int i, const uint64 x, const Z y)
		{
			auto gen_rec = [&](const auto &self, int i, const uint64 x, const Z y) -> void
			{
				powerful[x] += y;
				for (; i != P.size() && 1ULL * P[i] * P[i] <= N / x; ++i)
				{
					const uint64 Nx = N / x;
					const int p = P[i];
					uint64 pe = 1ULL * p * p;
					for (int e = 2; pe <= Nx; pe *= p, ++e)
					{
						Z fpe = f(pe, p, e);
						if (fpe.v)
							self(self, i + 1, x * pe, y * fpe);
					}
				}
			};
			return gen_rec(gen_rec, i, x, y);
		};
		gen(0, 1, 1);
		powerful.partial_sum();
		return mult_sparse(ds, powerful);
	};
	
	auto attach_small = [&](DS &ds, const std::function<Z (uint)> &f) -> DS & // no small p in `ds`!
	{
		ds.adjacent_difference();
		std::vector<int> pred(1 + R2 + 1);
		pred[1] = 0;
		for (int i = 2; i <= R2 + 1; ++i)
			pred[i] = ds.sv[i - 1].v ? i - 1 : pred[i - 1];
		for (int pid = L - 1; pid >= 0; --pid)
		{
			const int p = P[pid];
			Z y = f(p);
			{
				int j = 1, k = p;
				for (; (j + 1) * p - 1 <= R2; ++j)
					for (; k != (j + 1) * p; ++k)
						if (ds.lv[k].v)
							add(ds.lv[j], ds.lv[k], y);
				for (; k <= R2; ++k)
					if (ds.lv[k].v)
						add(ds.lv[j], ds.lv[k], y);
			}
			{
				int j = pred[R2 + 1];
				uint64 Nx = N / p;
				for (int X = R2 / p; j > X; j = pred[j])
					add(ds.lv[_udiv64(Nx, j)], ds.sv[j], y);
				int k = R2 + 1;
				for (; j; j = pred[j])
				{
					while (pred[k] > j * p)
						k = pred[k];
					// assert(k != j * p);
					pred[j * p] = pred[k], pred[k] = j * p;
					add(ds.sv[j * p], ds.sv[j], y);
				}
			}
		}
		ds.partial_sum();
		return ds;
	};
	
	auto eliminate_small = [&](DS &ds, const std::function<Z (uint)> &f) // no small p in `ds * f`
	{
		ds.adjacent_difference();
		std::vector<int> succ(1 + R2 + 1);
		succ[R2] = R2 + 1;
		for (int i = R2 - 1; i >= 0; --i)
			succ[i] = ds.sv[i + 1].v ? i + 1 : succ[i + 1];
		for (int pid = L - 1; pid >= 0; --pid)
		{
			const int p = P[pid];
			Z y = f(p);
			{
				int j = succ[0], k = succ[0];
				for (int X = R2 / p; j <= X; j = succ[j])
				{
					sub(ds.sv[j * p], ds.sv[j], y);
					while (succ[k] < j * p)
						k = succ[k];
					// assert(succ[k] == j * p);
					succ[k] = succ[j * p];
				}
				for (uint64 Nx = N / p; j <= R2; j = succ[j])
					sub(ds.lv[_udiv64(Nx, j)], ds.sv[j], y);
			}
			{
				int j = R2 / p, k = R2;
				for (; j; --j)
					for (; k >= j * p; --k)
						if (ds.lv[k].v)
							sub(ds.lv[j], ds.lv[k], y);
			}
		}
		ds.partial_sum();
		return ds;
	};
	
	auto attach_small_inv = [&](DS &ds, const std::function<Z (uint)> &f) -> DS & // no small p in `ds`! // 未经测试
	{
		ds.adjacent_difference();
		std::vector<int> succ(1 + R2 + 1);
		succ[R2] = R2 + 1;
		for (int i = R2 - 1; i >= 0; --i)
			succ[i] = ds.sv[i + 1].v ? i + 1 : succ[i + 1];
		for (int pid = 0; pid < L; ++pid)
		{
			const int p = P[pid];
			Z y = f(p);
			{
				int j = succ[0], k = succ[0];
				for (int X = R2 / p; j <= X; j = succ[j])
				{
					sub(ds.sv[j * p], ds.sv[j], y);
					while (succ[k] < j * p)
						k = succ[k];
					// assert(succ[k] != j * p);
					succ[j * p] = succ[k], succ[k] = j * p;
				}
				for (uint64 Nx = N / p; j <= R2; j = succ[j])
					sub(ds.lv[_udiv64(Nx, j)], ds.sv[j], y);
			}
			{
				int j = R2 / p, k = R2;
				for (; j; --j)
					for (; k >= j * p; --k)
						if (ds.lv[k].v)
							sub(ds.lv[j], ds.lv[k], y);
			}
		}
		ds.partial_sum();
		return ds;
	};
	
	auto eliminate_small_inv = [&](DS &ds, const std::function<Z (uint)> &f) // no small p in `res / f`!
	{
		ds.adjacent_difference();
		std::vector<int> pred(1 + R2 + 1);
		pred[1] = 0;
		for (int i = 2; i <= R2 + 1; ++i)
			pred[i] = ds.sv[i - 1].v ? i - 1 : pred[i - 1];
		for (int pid = 0; pid < L; ++pid)
		{
			const int p = P[pid];
			Z y = f(p);
			{
				int j = 1, k = p;
				for (; (j + 1) * p - 1 <= R2; ++j)
					for (; k != (j + 1) * p; ++k)
						if (ds.lv[k].v)
							add(ds.lv[j], ds.lv[k], y);
				for (; k <= R2; ++k)
					if (ds.lv[k].v)
						add(ds.lv[j], ds.lv[k], y);
			}
			{
				int j = pred[R2 + 1];
				uint64 Nx = N / p;
				for (int X = R2 / p; j > X; j = pred[j])
					add(ds.lv[_udiv64(Nx, j)], ds.sv[j], y);
				int k = R2 + 1;
				for (; j; j = pred[j])
				{
					while (pred[k] > j * p)
						k = pred[k];
					// assert(pred[k] == j * p);
					pred[k] = pred[j * p];
					add(ds.sv[j * p], ds.sv[j], y);
				}
			}
		}
		ds.partial_sum();
		return ds;
	};
	
	auto calc_medium = [&](const std::function<Z (uint)> &f)
	{
		DS l;
		for (int pid = L; pid != P.size(); ++pid)
		{
			const int p = P[pid];
			const Z y = f(p);
			
			int E = 1;
			Z yp = y;
			for (uint64 pp = p; pp <= N; pp *= p, yp *= -y, ++E)
				l[pp] += yp * _Rec[E];
		}
		l.partial_sum();
		
		DS res = l;
		for (int i = 1; i <= R2; ++i)
			res.sv[i] += 1, res.lv[i] += 1;
		DS lp = l * l;
		Z r = _Rec[2];
		for (int i = 2; i <= 5; ++i)
		{
			for (int j = 1; j <= R2; ++j)
				add(res.sv[j], lp.sv[j], r), add(res.lv[j], lp.lv[j], r);
			if (i != 5)
			{
				lp = lp * l;
				r *= _Rec[i + 1];
			}
		}
		return res;
	};
	
	auto calc_large = [&](const std::function<Z (uint64)> &f, const std::function<Z (uint64)> &ps)
	{
		auto fp = [&](uint p) { return f(p); };
		auto fpe = [&](uint64 pp, uint p, uint e) { return f(pp); };
		
		DS ds = calc_medium(fp);
		ds = attach_powerful(attach_small(ds, fp), fpe);
		DS res;
		for (int i = R2; i >= 1; --i)
		{
			Z x = ps(N / i) - ds.lv[i];
			for (int j = 2; i * j <= R2; ++j)
				sub(x, f(j), res.lv[i * j]);
			res.lv[i] = x;
		}
		return res;
	};
	
	auto mult_large = [&](DS &&ds, const DS &l)
	{
		for (int i = 1; i <= R2; ++i)
		{
			Z &x = ds.lv[i];
			for (int j = 1; i * j <= R2; ++j)
				if (ds.sv[j] != ds.sv[j - 1])
					add(x, ds.sv[j] - ds.sv[j - 1], l.lv[i * j]);
		}
		return ds;
	};
	DS l0 = calc_large(
		[&](uint64 n) { return 1; },
		[&](uint64 n) { return Z(n % Mod); }
	);
	DS l1 = calc_large(
		[&](uint64 n) { return Z(n % Mod); },
		[&](uint64 n) { return n %= Mod, Z(n * (n + 1) / 2 % Mod); }
	);
	DS l;
	for (int i = 1; i <= R2; ++i)
		l.lv[i] = A * l0.lv[i] + B * l1.lv[i];
	
	auto fp = [&](uint p) { return A + B * p; };
	auto fpe = [&](uint64 pp, uint p, uint e) { return A * e + B * p; };
	
	DS res = mult_large(calc_medium(fp), l);
	return attach_powerful(attach_small(res, fp), fpe);
}

#include <ctime>

int main(int argc, char **argv)
{
	int T;
	scanf("%u", &T);
	while (T--)
	{
		uint64 n;
		Z a, b;
		
		scanf("%llu %u %u", &n, &a.v, &b.v);
		
		DS ds = calc(n, a, b);
		
		std::vector<Z> res(ds.sv.begin() + 1, ds.sv.end());
		res.insert(res.end(), ds.lv.begin() + 1, ds.lv.end());
		std::sort(res.begin(), res.end(), [](const Z a, const Z b) { return a.v < b.v; });
		res.erase(std::unique(res.begin(), res.end()), res.end());
		uint Ans = 0;
		for (auto x : res)
			Ans ^= x.v;
		printf("%u\n", Ans);
	}
	fprintf(stderr, "%ld\n", clock());
	
	return 0;
}
/*

























































































































































#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
using LL = long long;

const int maxn = 4e5 + 5;
const LL INF = 1e18;

struct Point{
    LL a, b;

    Point(LL a = 0, LL b = INF) : a(a), b(b) {}

    LL val(LL x){
        return a * x + b;
    }

    Point operator-(Point t){
        return {a - t.a, b - t.b};
    }

};

int sign(__int128_t t){
    if (t > 0) return 1;
    if (t < 0) return -1;
    return 0;
}

int check(Point a, Point b){
    return sign(__int128_t(a.a) * b.b - __int128_t(a.b) * b.a);
}

int check(Point a, Point b, Point c){
    return check(b - a, c - b);
}

namespace SGT{

vector<Point> tr[maxn * 4];
int pt[maxn * 4];

void modify(int u, int l, int r, int x, Point line){
    while(tr[u].size() >= 2 and check(tr[u][tr[u].size() - 2], tr[u].back(), line) >= 0){
        tr[u].pop_back();
    }
    tr[u].push_back(line);
    if (l == r) return;
    int mid = (l + r) / 2;
    if (x <= mid) modify(2 * u, l, mid, x, line);
    else modify(2 * u + 1, mid + 1, r, x, line);
}

LL query(int u, LL x){
    while(pt[u] + 1 < tr[u].size() and tr[u][pt[u]].val(x) >= tr[u][pt[u] + 1].val(x)){
        pt[u]++;
    }
    return tr[u][pt[u]].val(x);
}

LL query(int u, int l, int r, int L, int R, LL x){
    if (l > R or r < L) return INF;
    if (l >= L and r <= R){
        return query(u, x);
    }
    int mid = (l + r) / 2;
    return min(query(2 * u, l, mid, L, R, x), query(2 * u + 1, mid + 1, r, L, R, x));
}

}

namespace Convex{

Point stk[maxn];
int top;

struct Event{
    int top, pos;
    Point p;
};

vector<Event> ops;

void push_back(Point line){
    if (top <= 1){
        ops.push_back({top, top + 1, stk[top + 1]});
        stk[++top] = line;
        return;
    }
    int l = 2, r = top + 1;
    while(l < r){
        int mid = (l + r + 1) / 2;
        if (check(stk[mid - 2], stk[mid - 1], line) >= 0) r = mid - 1;
        else l = mid;
    }
    ops.push_back({top, r, stk[r]});
    stk[top = r] = line;
}

void undo(){
    auto [_top, pos, p] = ops.back();
    ops.pop_back();
    top = _top;
    stk[pos] = p;
}

LL query(LL x){
    int l = 1, r = top;
    while(l < r){
        int mid = (l + r) / 2;
        if (stk[mid + 1].val(x) <= stk[mid].val(x)) l = mid + 1;
        else r = mid;
    }
    return stk[r].val(x);
}

}

LL dp[maxn], x[maxn], y[maxn];
pair<LL, LL> p[maxn];

int main(){

#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, k;
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> p[i].first >> p[i].second;
    }
    sort(p + 1, p + n + 1);
    for(int i = 1; i <= n; i++){
        tie(x[i], y[i]) = p[i];
    }
    // for(int i = 1; i <= n; i++){
    //     cout << x[i] << ' ' << y[i] << '\n';
    // }
    y[0] = INF;
    vector<int> stk{0};
    for(int i = 1; i <= n; i++){
        while(y[stk.back()] <= y[i]){
            Convex::undo();
            stk.pop_back();
        }
        SGT::modify(1, 1, n, i, {k - x[i], dp[i - 1]});
        Point line = {y[i], SGT::query(1, 1, n, stk.back() + 1, i, y[i])};
        Convex::push_back(line);
        dp[i] = Convex::query(x[i]);
        stk.push_back(i);
    }
    // for(int i = 1; i <= n; i++){
    //     cout << dp[i] << '\n';
    // }
    cout << dp[n] << '\n';

}#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
using LL = long long;

const int maxn = 4e5 + 5;
const LL INF = 1e18;

struct Point{
    LL a, b;

    Point(LL a = 0, LL b = INF) : a(a), b(b) {}

    LL val(LL x){
        return a * x + b;
    }

    Point operator-(Point t){
        return {a - t.a, b - t.b};
    }

};

int sign(__int128_t t){
    if (t > 0) return 1;
    if (t < 0) return -1;
    return 0;
}

int check(Point a, Point b){
    return sign(__int128_t(a.a) * b.b - __int128_t(a.b) * b.a);
}

int check(Point a, Point b, Point c){
    return check(b - a, c - b);
}

namespace SGT{

vector<Point> tr[maxn * 4];
int pt[maxn * 4];

void modify(int u, int l, int r, int x, Point line){
    while(tr[u].size() >= 2 and check(tr[u][tr[u].size() - 2], tr[u].back(), line) >= 0){
        tr[u].pop_back();
    }
    tr[u].push_back(line);
    if (l == r) return;
    int mid = (l + r) / 2;
    if (x <= mid) modify(2 * u, l, mid, x, line);
    else modify(2 * u + 1, mid + 1, r, x, line);
}

LL query(int u, LL x){
    while(pt[u] + 1 < tr[u].size() and tr[u][pt[u]].val(x) >= tr[u][pt[u] + 1].val(x)){
        pt[u]++;
    }
    return tr[u][pt[u]].val(x);
}

LL query(int u, int l, int r, int L, int R, LL x){
    if (l > R or r < L) return INF;
    if (l >= L and r <= R){
        return query(u, x);
    }
    int mid = (l + r) / 2;
    return min(query(2 * u, l, mid, L, R, x), query(2 * u + 1, mid + 1, r, L, R, x));
}

}

namespace Convex{

Point stk[maxn];
int top;

struct Event{
    int top, pos;
    Point p;
};

vector<Event> ops;

void push_back(Point line){
    if (top <= 1){
        ops.push_back({top, top + 1, stk[top + 1]});
        stk[++top] = line;
        return;
    }
    int l = 2, r = top + 1;
    while(l < r){
        int mid = (l + r + 1) / 2;
        if (check(stk[mid - 2], stk[mid - 1], line) >= 0) r = mid - 1;
        else l = mid;
    }
    ops.push_back({top, r, stk[r]});
    stk[top = r] = line;
}

void undo(){
    auto [_top, pos, p] = ops.back();
    ops.pop_back();
    top = _top;
    stk[pos] = p;
}

LL query(LL x){
    int l = 1, r = top;
    while(l < r){
        int mid = (l + r) / 2;
        if (stk[mid + 1].val(x) <= stk[mid].val(x)) l = mid + 1;
        else r = mid;
    }
    return stk[r].val(x);
}

}

LL dp[maxn], x[maxn], y[maxn];
pair<LL, LL> p[maxn];

int main(){

#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, k;
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> p[i].first >> p[i].second;
    }
    sort(p + 1, p + n + 1);
    for(int i = 1; i <= n; i++){
        tie(x[i], y[i]) = p[i];
    }
    // for(int i = 1; i <= n; i++){
    //     cout << x[i] << ' ' << y[i] << '\n';
    // }
    y[0] = INF;
    vector<int> stk{0};
    for(int i = 1; i <= n; i++){
        while(y[stk.back()] <= y[i]){
            Convex::undo();
            stk.pop_back();
        }
        SGT::modify(1, 1, n, i, {k - x[i], dp[i - 1]});
        Point line = {y[i], SGT::query(1, 1, n, stk.back() + 1, i, y[i])};
        Convex::push_back(line);
        dp[i] = Convex::query(x[i]);
        stk.push_back(i);
    }
    // for(int i = 1; i <= n; i++){
    //     cout << dp[i] << '\n';
    // }
    cout << dp[n] << '\n';

}#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
using LL = long long;

const int maxn = 4e5 + 5;
const LL INF = 1e18;

struct Point{
    LL a, b;

    Point(LL a = 0, LL b = INF) : a(a), b(b) {}

    LL val(LL x){
        return a * x + b;
    }

    Point operator-(Point t){
        return {a - t.a, b - t.b};
    }

};

int sign(__int128_t t){
    if (t > 0) return 1;
    if (t < 0) return -1;
    return 0;
}

int check(Point a, Point b){
    return sign(__int128_t(a.a) * b.b - __int128_t(a.b) * b.a);
}

int check(Point a, Point b, Point c){
    return check(b - a, c - b);
}

namespace SGT{

vector<Point> tr[maxn * 4];
int pt[maxn * 4];

void modify(int u, int l, int r, int x, Point line){
    while(tr[u].size() >= 2 and check(tr[u][tr[u].size() - 2], tr[u].back(), line) >= 0){
        tr[u].pop_back();
    }
    tr[u].push_back(line);
    if (l == r) return;
    int mid = (l + r) / 2;
    if (x <= mid) modify(2 * u, l, mid, x, line);
    else modify(2 * u + 1, mid + 1, r, x, line);
}

LL query(int u, LL x){
    while(pt[u] + 1 < tr[u].size() and tr[u][pt[u]].val(x) >= tr[u][pt[u] + 1].val(x)){
        pt[u]++;
    }
    return tr[u][pt[u]].val(x);
}

LL query(int u, int l, int r, int L, int R, LL x){
    if (l > R or r < L) return INF;
    if (l >= L and r <= R){
        return query(u, x);
    }
    int mid = (l + r) / 2;
    return min(query(2 * u, l, mid, L, R, x), query(2 * u + 1, mid + 1, r, L, R, x));
}

}

namespace Convex{

Point stk[maxn];
int top;

struct Event{
    int top, pos;
    Point p;
};

vector<Event> ops;

void push_back(Point line){
    if (top <= 1){
        ops.push_back({top, top + 1, stk[top + 1]});
        stk[++top] = line;
        return;
    }
    int l = 2, r = top + 1;
    while(l < r){
        int mid = (l + r + 1) / 2;
        if (check(stk[mid - 2], stk[mid - 1], line) >= 0) r = mid - 1;
        else l = mid;
    }
    ops.push_back({top, r, stk[r]});
    stk[top = r] = line;
}

void undo(){
    auto [_top, pos, p] = ops.back();
    ops.pop_back();
    top = _top;
    stk[pos] = p;
}

LL query(LL x){
    int l = 1, r = top;
    while(l < r){
        int mid = (l + r) / 2;
        if (stk[mid + 1].val(x) <= stk[mid].val(x)) l = mid + 1;
        else r = mid;
    }
    return stk[r].val(x);
}

}

LL dp[maxn], x[maxn], y[maxn];
pair<LL, LL> p[maxn];

int main(){

#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, k;
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> p[i].first >> p[i].second;
    }
    sort(p + 1, p + n + 1);
    for(int i = 1; i <= n; i++){
        tie(x[i], y[i]) = p[i];
    }
    // for(int i = 1; i <= n; i++){
    //     cout << x[i] << ' ' << y[i] << '\n';
    // }
    y[0] = INF;
    vector<int> stk{0};
    for(int i = 1; i <= n; i++){
        while(y[stk.back()] <= y[i]){
            Convex::undo();
            stk.pop_back();
        }
        SGT::modify(1, 1, n, i, {k - x[i], dp[i - 1]});
        Point line = {y[i], SGT::query(1, 1, n, stk.back() + 1, i, y[i])};
        Convex::push_back(line);
        dp[i] = Convex::query(x[i]);
        stk.push_back(i);
    }
    // for(int i = 1; i <= n; i++){
    //     cout << dp[i] << '\n';
    // }
    cout << dp[n] << '\n';

}

*/

詳細信息

Test #1:

score: 100
Accepted
time: 423ms
memory: 4312kb

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:

6702293
422200583
304441446
69351732
421157478
210560518
504474449
12692533
331877891
385355840
275328665
310397326
67866328
533036893
27246365
72866646
467021279
34647362
411996318
297571277
334576259
221391996
496297771
222601160
232748202
470542910
115812226
192533857
361627876
443138779
2575036
...

result:

ok 10000 numbers

Test #2:

score: 0
Accepted
time: 320ms
memory: 4224kb

input:

486
685583 192056743 391870214
272484 346225796 149350515
656101 326831808 112167252
22515 203348552 60773766
1633155 194072757 22284059
57727 404929471 327406577
57598 251468713 173130016
1102497 36566124 195330260
3504399 214678339 86082351
360127 323967709 231892988
11663 225570343 56772624
39921...

output:

434223382
116245445
125541760
160318550
446061234
484145141
518392434
81977168
17947265
307371543
407160883
335339263
39598998
470162878
410893643
26179198
26198426
40422957
398293380
265153607
228078198
293572568
155169142
224586788
375283776
8481447
491498721
350950775
534322011
64802753
436909146...

result:

ok 486 numbers

Test #3:

score: 0
Accepted
time: 289ms
memory: 4344kb

input:

351
2069283 349969193 52280365
1407781 304782674 71786142
2619526 356665139 467865678
128394 19761994 158668471
4868626 435554461 55057371
228834 394703499 184531829
516241 188565552 183063603
703082 128264745 446152032
2069281 460231072 101600517
1407654 181732896 221743073
6648661 455206481 450814...

output:

319910185
369336286
50213187
67975443
429652780
316610082
64991059
22778081
332789438
497599689
331161326
417226667
247312840
325206278
489998938
119792359
144611262
188956641
12934607
448204725
376317
505473640
338284847
49730199
138622978
88198200
362403025
187282938
318525939
107779358
59656206
2...

result:

ok 351 numbers

Test #4:

score: 0
Accepted
time: 212ms
memory: 4528kb

input:

333
1016064 204524889 390112646
535822 104757052 269069192
1557487 409444563 74927504
49155 283505698 318482175
6259987 190292359 349969193
112767 52280365 304782674
191842 71786142 356665139
248003 467865678 19761994
1016062 158668471 435554461
535695 55057371 394703499
4848803 184531829 188565552
...

output:

424757689
373968255
24290918
306982012
533936667
401990420
336964323
76114089
369506627
173872187
202999923
155205263
11081034
302738228
265042946
56046100
133964275
12419321
467153573
158929408
51479146
213214379
6763076
305753342
319915377
24381258
425402644
187212393
38116675
255693248
28212987
5...

result:

ok 333 numbers

Test #5:

score: 0
Accepted
time: 5854ms
memory: 186940kb

input:

1
9994070595599 209907780 360301068

output:

39200515

result:

ok 1 number(s): "39200515"

Test #6:

score: 0
Accepted
time: 5789ms
memory: 187136kb

input:

1
9999145190306 209907780 360301068

output:

48621786

result:

ok 1 number(s): "48621786"

Test #7:

score: 0
Accepted
time: 5648ms
memory: 182600kb

input:

1
9483578929763 209907780 360301068

output:

51012486

result:

ok 1 number(s): "51012486"

Extra Test:

score: 0
Extra Test Passed