CCPC威海 L&C

L Clock Master

求和为 \(n\) 的若干数的最大 \(LCM\)

\[n = p_{m_1}^{k_1} + p_{m_2}^{k_2} + ...+p_{m_n}^{k_n} \]

求最大的

\[ans = ln(p_{m_1}^{k_1}p_{m_2}^{k_2}...p_{m_n}^{k_n}) = k_1ln(p_{m_1}) + ...+k_nln(p_{m_n}) \]

分组背包

#include<bits/stdc++.h>
using namespace std;

const int N = 3e4 + 200;
int prime[N], cnt, vis[N];
double lg[N];
void init() {
	for (int i = 2; i < N; i++) {
		if (!vis[i])prime[++cnt] = i, lg[cnt] = log(i);
		for (int j = 1; j <= cnt and prime[j] * i < N; j++) {
			vis[prime[j] * i] = 1;
			if (!i % prime[j])break;
		}
	}
}
double f[N];
void cal() {
	for (int i = 1; i <= cnt; i++) {
		if (prime[i] >= N)break;
		for (int v = N - 1; v >= 0; v--) {
			int base = prime[i];
			for (int j = 0; j < 18; j++) {
				if (v < base)break;
				f[v] = max(f[v], f[v - base] + lg[i] * (j + 1));
				base *= prime[i];
			}
		}
	}
}
int main() {
	init();
	cal();
	int T, n;
	scanf("%d", &T);
	while (T--) {
		scanf("%d", &n);
		printf("%.6f\n", f[n]);
	}
}

C Rencontre

算边的贡献

#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
vector<int>G[N];
int x[N], y[N], w[N], dep[N];
int val[3][N];
int sum[3][N], m[3];
int n;

void dfs(int u, int p) {
	dep[u] = dep[p] + 1;
	for (int i = 0; i < 3; i++)sum[i][u] = val[i][u];
	if (G[u].size() == 1 and G[u][0] == p) {
		return;
	}
	
	for (int v : G[u]) {
		if (v == p)continue;
		dfs(v, u);
		for (int i = 0; i < 3; i++) {
			sum[i][u] += sum[i][v];
		}
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		scanf("%d%d%d", x + i, y + i, w + i);
		G[x[i]].push_back(y[i]); G[y[i]].push_back(x[i]);
	}
	double s = 1.0;
	for (int i = 0; i < 3; i++) {
		scanf("%d", &m[i]); s *= m[i];
		for (int j = 0; j < m[i]; j++) {
			int z; scanf("%d", &z);
			val[i][z] = 1;
		}
	}
	dfs(1, 0);
	double ans = 0.0;
	for (int i = 1; i < n; i++) {
		int u = x[i], v = y[i], ww = w[i];
		if (dep[u] < dep[v])swap(u, v);
		int s1 = sum[0][u], s2 = sum[1][u], s3 = sum[2][u];
		int r1 = m[0] - s1, r2 = m[1] - s2, r3 = m[2] - s3;
		ans += 1.0 * ww * s1 * r2 * r3 / s;
		ans += 1.0 * ww * r1 * s2 * r3 / s;
		ans += 1.0 * ww * r1 * r2 * s3 / s;
		ans += 1.0 * ww * r1 * s2 * s3 / s;
		ans += 1.0 * ww * s1 * r2 * s3 / s;
		ans += 1.0 * ww * s1 * s2 * r3 / s;
	}
	printf("%.9f\n", ans);
}
上一篇:MOOC数据结构PTA-03-树1 树的同构


下一篇:链队列基本操作模拟系统