CH1102 火车进出栈问题 数学

题目链接

http://noi-test.zzstep.com/contest/0x10%E3%80%8C%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E3%80%8D%E4%BE%8B%E9%A2%98/1102%20%E7%81%AB%E8%BD%A6%E8%BF%9B%E5%87%BA%E6%A0%88%E9%97%AE%E9%A2%98

分析

递推会超时,用通项公式求。

分子分母一起统计质因数分解式中各质因子次数,相减后累乘到结果中。

AC代码

#include 
#include 

inline int read() {
	int num = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9')
		num = num * 10 + c - '0', c = getchar();
	return num;
}

const int maxn = 6e4 + 5, maxb = 4e4 + 5;

struct BigInteger {
	int num[maxb], len;
	
	BigInteger(int x = 0) {
		memset(num, 0, sizeof(num));
		len = 1;
		while (x) num[len++] = x % 10, x /= 10;
		if (len > 1) --len;
	}

	BigInteger operator * (const int& rhs) const {
		BigInteger ans = *this;
		for (int i = 1; i <= ans.len; ++i) ans.num[i] *= rhs;
		for (int i = 1; i <= ans.len; ++i)
			for (int j = i; ans.num[j] > 9; ++j) {
				ans.num[j + 1] += ans.num[j] / 10;
				ans.num[j] %= 10;
			}
		ans.len += 10;
		while (!ans.num[ans.len] && ans.len > 1) --ans.len;
		return ans;
	}

	void print() {
		for (int i = len; i; --i) printf("%d", num[i]);
	}
} ans(1);

int vis[2 * maxn], prime[2 * maxn], tot;

int main() {
	int n = read();
	for (int i = 2; i <= 2 * n; ++i) {
		if (!vis[i]) prime[++tot] = i;
		for (int j = 1; j <= tot && i * prime[j] <= 2 * n; ++j) {
			vis[i * prime[j]] = 1;
			if (i % prime[j] == 0) break;
		}
	}
	for (int i = 1; i <= tot; ++i) {
		int a = 0, b = 0, c = 0;
		for (int j = prime[i]; j <= 2 * n; j *= prime[i])
			a += 2 * n / j, b += (n + 1) / j, c += n / j;
		for (int j = a - b - c; j; --j)
			ans = ans * prime[i];
	}
	ans.print();
	return 0;
}

你可能感兴趣的:(《算法竞赛进阶指南》)