暑假集训六 [接力比赛,树上竞技,虚构推理,记忆碎片]
暑假集训六
别问为什么从六开始。
题面
A.接力比赛
两个01背包跑一遍。
别问代码为啥写的这么阴间。
Code
#include<cstdio> #include<algorithm> using namespace std; const int MAXN = 1010, MAXV = 1e6 + 10; const long long INF = 1e18 + 1145141919810; int n, m; long long w, v, ans; long long sum_w[MAXN], sum_b[MAXN]; long long dp[2][MAXV]; bool vis_w[MAXV], vis_b[MAXV]; inline int read(){ int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } int main(){ freopen("game.in", "r", stdin); freopen("game.out", "w", stdout); n = read(), m = read(); vis_w[0] = true; for(register int i = 1; i <= n; i++){ w = read(), v = read(); sum_w[i] = sum_w[i - 1] + w; for(register int j = 1; j <= w; j++) dp[0][j + sum_w[i - 1]] = -INF; for(register int j = sum_w[i - 1]; j >= 0; j--){ if(vis_w[j]){ dp[0][j + w] = max(dp[0][j + w], dp[0][j] + v); vis_w[j + w] = true; } } } vis_b[0] = true; for(register int i = 1; i <= m; i++){ w = read(), v = read(); sum_b[i] = sum_b[i - 1] + w; for(register int j = 1; j <= w; j++) dp[1][j + sum_b[i - 1]] = -INF; for(register int j = sum_b[i - 1]; j >= 0; j--){ if(vis_b[j]){ dp[1][j + w] = max(dp[1][j + w], dp[1][j] + v); vis_b[j + w] = true; } } } long long len = max(sum_w[n], sum_b[m]); for(register int i = 1; i <= len; i++){ if(vis_w[i] && vis_b[i]) ans = max(ans, dp[0][i] + dp[1][i]); } printf("%lld", ans); return 0; }
B.树上竞技
按照边去考虑,如果在一条边 的两侧分别有 和 个关键点,
不妨令 那么最后的汇聚点一定在 这个方向,
这样可以只让 条边经过 ,代价较小
然后设某条边两侧分别共有 和 个点,容易发现我们需要求
发现 不是很好处理,考虑把它拆开来,还要加上 为偶数的情况,用 预处理节点子树大小,原式可以化成
后面的一小点式子可以暴力硬扫,考虑前面的怎样优化
不妨设 ,发现比较显然地,
不妨令 ,那么答案就是
考虑如何求出 ,发现它的组合意义是 个物品里选择了 个,前面 个物品中选择了 个的方案数
如何递推 ?
不难发现, 变成 变少的部分就是前 个点中选择 个,选择了 为第 个点,后面 个点里选择了 个点
这是为什么呢?我们考虑如果没有选择 作为第 个点
那么前 个点中选择 个点和前 个点中选择 个是等价的
所以必须让 作为第 个点被选择,多出来的方案数根据乘法原理就是
也就是说
统计答案即可。
算是偷的markdown。
Code
#include<cstdio> #include<algorithm> #define LL long long using namespace std; const int Mod = 1e9 + 7; const int MAXN = 1e6 + 10; int n, m, k, cnt; LL ans; int head[MAXN], size[MAXN]; LL fac[MAXN], inv[MAXN]; LL f[MAXN]; struct Edge{ int to, next; }e[MAXN << 1]; inline void Add(int u, int v){ e[++cnt].to = v; e[cnt].next = head[u]; head[u] = cnt; } LL Fast_Pow(LL a, LL w, LL p){ LL ans = 1; while(w){ if(w & 1) ans = ans * a % p; a = a * a % p; w >>= 1; } return ans; } LL Inv(LL a, LL p){ return Fast_Pow(a, p - 2, p); } LL C(LL n, LL m, LL p){ if(!m) return 1; if(m > n) return 0; return fac[n] * inv[m] % p * inv[n - m] % p; } void init(){ fac[1] = 1; for(register int i = 2; i <= n; i++) fac[i] = 1LL * fac[i - 1] * i % Mod; inv[n] = Inv(fac[n], Mod); for(register int i = n - 1; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % Mod; } void dfs(int rt, int fa){ size[rt] = 1; for(register int i = head[rt]; i; i = e[i].next){ int v = e[i].to; if(v == fa) continue; dfs(v, rt); size[rt] += size[v]; ans = 1LL * (ans + f[size[v]] % Mod + f[n - size[v]] % Mod) % Mod; if(!(m & 1)) ans = 1LL * (ans + C(size[v], m / 2, Mod) * C(n - size[v], m / 2, Mod) % Mod * (m / 2) % Mod) % Mod; } } inline int read(){ int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } int main(){ freopen("meeting.in", "r", stdin); freopen("meeting.out", "w", stdout); n = read(), m = read(); init(); for(register int i = 1; i <= n - 1; i++){ int u; u = read(); Add(u, i + 1); Add(i + 1, u); } k = (m - 1) / 2; if(k >= 1) f[1] = C(n - 1, m - 1, Mod); for(register int i = 2; i <= n; i++) f[i] = 1LL * ((f[i - 1] - C(i - 2, k - 1, Mod) * C(n - i, m - k - 1, Mod) % Mod) % Mod + Mod) % Mod; for(register int i = 2; i <= n; i++) f[i] = 1LL * f[i] * i % Mod; dfs(1, 0); printf("%lld", ans); return 0; }
C.虚构推理
其实不用题解那么麻烦,可以枚举时间再lower_bound
优化查询。
查询到和当前时间的角最大的时间就可以。
Code
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 5e4 + 10; const long double EPS = 1e-10; int n; long double ans = 1e10; long double angle_h[MAXN], angle_m[MAXN]; struct Clock{ int h, m, s; }c[MAXN]; inline long double fmax(long double x, long double y){ return (x - y > EPS) ? x : y; } inline long double fmin(long double x, long double y){ return (y - x > EPS) ? x : y; } inline long double fabs(long double x){ return (0 - x > EPS) ? -x : x; } long double Get_Cut(long double angle1, long double angle2){ return fmin(fabs(angle1 - angle2), 360.0 - fabs(angle1 - angle2)); } long double Find_Cut(long double angle, long double *clock){ int pos1, pos2; if(180.0 - angle > EPS){ pos1 = lower_bound(clock + 1, clock + 1 + n, angle + 180.0) - clock; pos2 = pos1 - 1; } else{ pos1 = lower_bound(clock + 1, clock + 1 + n, angle - 180.0) - clock; pos2 = pos1 - 1; } if(pos1 == n + 1) pos1 = 1; if(pos2 == 0) pos2 = n; return fmax(Get_Cut(angle, clock[pos1]), Get_Cut(angle, clock[pos2])); } int main(){ freopen("unreal.in", "r", stdin); freopen("unreal.out", "w", stdout); scanf("%d", &n); for(register int i = 1; i <= n; i++){ scanf("%d:%d:%d", &c[i].h, &c[i].m, &c[i].s); if(c[i].h >= 12) c[i].h -= 12; angle_m[i] = 1.0 * c[i].m * 6.0 + c[i].s * 0.1; angle_h[i] = 1.0 * c[i].h * 30.0 + c[i].m * 0.5 + c[i].s / 120.0; } sort(angle_m + 1, angle_m + 1 + n); sort(angle_h + 1, angle_h + 1 + n); for(register long double h = 0; h < 12; h++){ for(register long double m = 0; m < 60; m++){ for(register long double s = 0; s < 60; s += 0.1){ long double m_angle = 1.0 * m * 6.0 + s * 0.1; long double h_angle = 1.0 * h * 30.0 + m * 0.5 + s / 120.0; ans = fmin(ans, fmax(Find_Cut(m_angle, angle_m), Find_Cut(h_angle, angle_h))); } } } printf("%Lf", ans); return 0; }
D.记忆碎片
不会,可以去看Delov 大佬的题解
或者SoyTony大佬的题解
以下为博客签名,与博文无关。
只要你们不停下来,那前面就一定有我。所以啊,不要停下来~
本文来自博客园,作者:TSTYFST,转载请注明原文链接:https://www.cnblogs.com/TSTYFST/p/16600258.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理