#include<bits/stdc++.h> #define int long long usingnamespace std; int dp[1000010][10]; constint MOD = 998244353; signedmain(){ int n; std::cin >> n; for (int i = 1; i <= 9; i++) dp[1][i] = 1; for (int i = 2; i <= n; i++) { for (int j = 1; j <= 9; j++) { for (int it : {-1, 0, 1}) { int now = j - it; if (now <= 9 && now >= 1) { dp[i][j] = (dp[i][j] + dp[i-1][now]) % MOD; } } } } int ans = 0; for (int i = 1; i <= 9; i++) { ans = (ans + dp[n][i]) % MOD; } cout << ans << endl; return0; }
D - ABC Transform
给定一个初始的字符串s 由’A’, ‘B’, ‘C’构成
给定q个询问 每个询问有一个t, k ($t\in [0, 10^{18}],k \in [1,10^{18}]$)
intmain(){ int tt, ans; std::cin >> tt; longlong n; std::set <longlong> s; std::vector <longlong> frac; longlong sum = 1, tot = 2; do { s.insert(sum); sum *= tot++; } while (sum <= 1e12); sum = 1; do { s.insert(sum); sum *= 2; } while (sum <= 1e12);
frac.push_back(0); for (auto it : s) frac.push_back(it);
std::vector <longlong> count(60, 0); for (int i = 1; i < frac.size(); i++) count[i] = count[i-1] + frac[i];
auto dfs = [&](auto self, int now, longlong tem, int cnt) -> void { if (tem > n) return; if (cnt > ans) return; if (tem == n) ans = std::min(cnt, ans); if (tem + count[now - 1] < n) return; for (int i = now - 1; i >= 1; i--) { self(self, i, tem + frac[i], cnt + 1); } }; while (tt--) { ans = INT_MAX; std::cin >> n; dfs(dfs, frac.size(), 0ll, 0); if (ans == INT_MAX) puts("-1"); else std::cout << ans << std::endl; } return0; }
官方题解的思路还是非常老套的从二进制位上考虑
emmm 快速看了一下 大致思路是 枚举15个阶乘数的选取情况
剩下的位数用2的次幂不上 最后一个二进制下等于n 感觉也不是很妙..
他们怎么都想到这么做了..
#include<bits/stdc++.h>
intmain(){ int tt; std::cin >> tt; longlong fac[15], t = 1; for (int i = 1; i <= 15; i++) t *= i, fac[i-1] = t; while (tt--) { longlong n; std::cin >> n; int ans = 100;
for (int i = 0; i < pow(2, 15); ++i) { std::bitset<15>b(i); longlong t = n; for (int j = 0; j < 15; j++) t -= b[j] * fac[j]; if (t >= 0) { std::bitset <64> b1(t); ans = std::min(ans, (int)(b.count() + b1.count())); } } std::cout << ans << '\n'; } return0; }
auto dfs = [&](auto self, int now, longlong tem, int cnt) -> void { if (tem > n) return; if (cnt > ans) return; if (tem == n) ans = std::min(cnt, ans); // if (tem + count[now - 1] < n) return; for (int i = now - 1; i >= 1; i--) { if (tem + count[i] < n) return; self(self, i, tem + frac[i], cnt + 1); } };
auto dfs = [&](auto self, int u, int fa) -> void { dp[0][u] = 0, dp[1][u] = 1; w[0][u] = 1, w[1][u] = e[u].size(); for (auto v : e[u]) { if (v == fa) continue; self(self, v, u);
auto tot = [&](auto self, int u, int fa, int op) -> void { if (op == 1) val[u] = e[u].size(); else val[u] = 1; for (auto v : e[u]) { if (v == fa) continue; if (op == 1) { self(self, v, u, 0); } else { if (dp[0][v] > dp[1][v] || (dp[0][v] == dp[1][v] && w[0][v] < w[1][v])) self(self, v, u, 0); else self(self, v, u, 1); } }
};
for (int i = 1; i < n; i++) { int u, v; std::cin >> u >> v; e[u].push_back(v), e[v].push_back(u); } if (n == 2) { puts("2 2\n1 1"); return0; } dfs(dfs, 1, 0); // 随便定一个根 rt = 1 if (dp[0][1] > dp[1][1] || (dp[0][1] == dp[1][1] && w[0][1] < w[1][1])) { std::cout << dp[0][1] << ' ' << w[0][1] << '\n'; tot(tot, 1, 0, 0); } else { std::cout << dp[1][1] << ' ' << w[1][1] << '\n'; tot(tot, 1, 0, 1); } for (int i = 1; i <= n; i++) std::cout << val[i] << ' '; return0; }
signedmain(){ longlong n, m; std::cin >> n >> m; std::vector frac(23, 0ll); std::bitset <20*1000000> vis; std::bitset <1000000> num; int cnt = 0;
for (int i = 1; i <= 20; i++) { for (int j = 1; j <= m; j++) { if (vis[i * j] == 0) cnt++; vis[i * j] = 1; } frac[i] = cnt; } longlong ans = 1;
for (int i = 2; i <= n; i++) { if (num[i]) continue; longlong j = 1, now = i; while (now <= n) { num[now] = 1; j++, now *= i; } j--; ans += frac[j]; } std::cout << ans << '\n'; return0; }