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
", 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
", ans);
}