11.18 解题报告
总的来说没挂分,因为没啥分可以挂了。
预计得分 : 60 + 0 + 20 + 20
实际得分: 60 + 0 + 15 + 20
A
预计得分 : 60
实际得分: 60
写了 n^2 的暴力 + 特殊性质
特殊性质用暴力来写的,看了一下可以 推。
更正的代码:
想起来了,我没更正代码:
#include <bits/stdc++.h> #define pb push_back #define lson rt << 1 #define rson rt << 1 | 1 using namespace std; typedef long long ll; const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; inline int read() { int res = 0, f = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) f |= (ch == '-'); for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch - '0'); return f ? -res : res; } int n, a[N], b[N]; ll ans = 0, dp[N]; namespace Sub1 { void Main() { ll cur = 10, js = 5; dp[1] = 0, dp[2] = 1, dp[3] = 4, dp[4] = 10; for(int i = 5; i <= n; i++) dp[i] = dp[i - 1] + cur, cur = (cur + js), js++; cout << dp[n] << '\n'; exit(0); } } signed main() { freopen("swap.in", "r", stdin); freopen("swap.out", "w", stdout); n = read(); for(int i = 1; i <= n; i++) b[i] = n - i + 1; for(int i = 1; i <= n; i++) a[i] = read(); int f = 0; for(int i = 1; i <= n; i++) f |= (a[i] != b[i]); if(!f) Sub1::Main(); for(int i = 1; i <= n; i++) { if(a[i] == i) continue; int wz = 0; for(int j = i + 1; j <= n; j++) if(a[j] == i) { wz = j; break;} for(int j = wz; j > i; j--) ans += abs(a[j] - a[j - 1]), swap(a[j], a[j - 1]); } cout << ans << '\n'; return 0; } /* 这是一个 1~n 的排列 就是转换成了给你一个序列,把他变成 1~n 的序列 每个位置该去哪已经固定了 那怎样能使代价最小呢/hsh 昨晚做了个一样的题,那个是 n^2 的做法 先写个 n^2 的暴力看看 写完暴力了,感觉就是对于前后差值绝对值的一段区间进行翻转? 好像是套个文艺平衡树就可以在 n log n 做完了 可惜我早忘了怎么写了 /hsh 看看特殊性质的分数怎么写吧 现在有 60 分 特殊性质是倒序排列的 可以 O(n) 推出来 3 3 2 1 4 4 4 3 2 1 10 5 5 4 3 2 1 20 6 6 5 4 3 2 1 35 7 7 6 5 4 3 2 1 56 8 8 7 6 5 4 3 2 1 84 3 4 5 6 7 8 9 10 11 0 1 4 10 20 35 56 84 120 165 220 + 286 1 3 4 6 10 15 21 28 + 36 + 45 + 55 + 66 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 */
B
搜索太难写了,写了很长时间没草出来了。
#include <bits/stdc++.h> #define pb push_back #define lson rt << 1 #define rson rt << 1 | 1 using namespace std; #define int long long const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; const int Mod = 998244353; inline int read() { int res = 0, f = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) f |= (ch == '-'); for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch - '0'); return f ? -res : res; } /* n = k 和 k <= 20 的话,感觉比较好写? k = 20 的话就是暴力了吧 n = k 说明了只要能选到 1 位置就行了 于是特殊性质的题目就转换成了: 有 n 个数字,期望多少轮能选 1 n <= 500 先手摸几组算算吧/hsh 第一轮选1的期望+第二轮选1的期望+……+第n轮选1的期望就是答案 1/n * 1 + (n - 1) * 1 / (n - 1) * 2 + 感觉不是很好写啊,没学过数学期望 /hsh */ int n, k, a[N]; int fz, fm; std::bitset <N> vis; inline int gcd(int a, int b) { return !b ? a : gcd(b, a % b); } inline void tf(int &a, int &b, int c, int d) { if(!a || !b) { a = c, b = d; return;} int FM = b * d, Fz = a * d + b * c; a = Fz, b = FM; int Gcd = gcd(a, b); a /= Gcd, b /= Gcd; } inline int ksm(int a, int b) { int res = 1; while(b) { if(b & 1) res = (res * a) % Mod; a = (a * a) % Mod, b >>= 1; } return res % Mod; } // Start: 10:35 Finish: // 首先要知道这是第x轮把1拿走,然后只会造成 x / sum 的贡献 // 直接强行用分数来替换成整数做就行了吧 // 问题是找能到达的最近的棋子。 // 1 1 0 1 1 0 // 破环成链然后从左边找,从右边找就行了 // 我觉得应该是给了 dfs 15 分,whq 不能这么绝情/hsh // 现在还有 1.5h 我还有2个题的暴力没有写啊/fn // 不会写 dfs啊,看不懂样例 // 首先每一轮都会把一个棋子整没 // 所以搜索最多搜索 k 层 inline int get(int pos) { int l = pos, r = pos; for(int i = pos; i >= 1; i--) if(vis[i]) { l = i; break;} for(int i = pos; i <= 2 * n; i++) if(vis[i]) { r = i; break;} if(pos - l <= r - pos) return l; else return r; } inline void cclear(int x) { if(x >= 1 && x <= n) vis[x] = vis[x + n] = 0; else vis[x] = vis[x - n] = 0; } inline void Cover(int x) { if(x >= 1 && x <= n) vis[x] = vis[x + n] = 1; else vis[x] = vis[x + n] = 1; } bool qwq[N]; // 写不出 T2 的期望爆搜了 /hsh // 再写30min,写不出来就溜了/hsh // 真的不会写啊,现在的得分情况最优是 60 + 0 + 0 + 20 还没过百啊 /hsh // 光写一下 n = k 的部分分吧 // sb 才写,去写一下 T3 的20分 // 现在最优得分是 : 60 + 0 + 20 + 20 = 100 /jy // mb 啥也不会写,出的题很好,就是我看不大懂题目/hsh // md 光在写碎碎念了,题到是没写多少/hsh // 40 分钟我先去理解一下题目吧 // 最后10分钟的时候我去收拾文件夹 inline void dfs(int step, int Sum, int pre) { if(step == k + 1) { tf(fz, fm, pre, Sum); return; } for(int i = 1; i <= n; i++) { int wz = get(i); cclear(wz); if(pre == 1) dfs(step + 1, Sum * n % Mod, pre * n % Mod); else if(wz == 1) dfs(step + 1, Sum * n % Mod, 1); else dfs(step + 1, Sum * n % Mod, pre); Cover(wz); } } signed main() { freopen("game.in", "r", stdin); freopen("game.out", "w", stdout); n = read(), k = read(); for(int i = 1; i <= k; i++) a[i] = read(), vis[a[i]] = 1; for(int i = 1; i <= n; i++) vis[i + n] = vis[i]; dfs(1, 1, 0); cout << (fz * ksm(fm, Mod - 2)) % Mod; putchar('\n'); return 0; }
C
一个很难读懂题的题。
读了很长时间,猜了个意思,然后过了大样例就跑了。
#include <bits/stdc++.h> #define pb push_back #define lson rt << 1 #define rson rt << 1 | 1 using namespace std; typedef long long ll; const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; const int Mod = 998244353; inline int read() { int res = 0, f = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) f |= (ch == '-'); for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch - '0'); return f ? -res : res; } struct Edge { int v, nxt;} e[N]; ll ans = 0; int n, type, head[N], num_edge = 0, siz[N], fa[N]; inline void add_edge(int u, int v) { e[++num_edge] = (Edge) { v, head[u]}, head[u] = num_edge;} inline void dfs(int u, int Fa) { fa[u] = Fa; for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if(v == Fa) continue; siz[u]++; dfs(v, u); } } struct qwq { int a, b, c, d; } p[N]; int stc[N], sc = 0; int ans1, ans2 = 0; int cnt[N]; namespace Sub2 { void Main() { for(register int b = 1; b <= n; b++) { int a = fa[b]; for(register int i = head[a]; i; i = e[i].nxt) { int c = e[i].v; if(c == b || c == fa[a]) continue; for(int j = head[b]; j; j = e[j].nxt) { int d = e[j].v; if(d == a) continue; p[++ans] = (qwq) {a, b,c, d}; if(ans > Mod) ans -= Mod; } } } } } // 我再把这些满足条件的四元组去dfs,然后判断? // 那这样有20分,好像可以过100了 // 有20分了/fn bool Check(qwq a, qwq b) { cnt[a.a] = 0, cnt[a.b] = 0, cnt[a.c] = 0, cnt[a.d] = 0, cnt[b.a] = 0, cnt[b.b] = 0, cnt[b.c] = 0, cnt[b.d] = 0; cnt[a.a]++, cnt[a.b]++, cnt[a.c]++, cnt[a.d]++, cnt[b.a]++, cnt[b.b]++, cnt[b.c]++, cnt[b.d]++; if(cnt[a.a] > 1 || cnt[a.b] > 1 || cnt[a.c] > 1 || cnt[a.d] > 1) return false; if(cnt[b.a] > 1 || cnt[b.b] > 1 || cnt[b.c] > 1 || cnt[b.d] > 1) return false; return true; } bool Judge() { for(int i = 1; i <= sc; i++) { for(int j = i + 1; j <= sc; j++) { if(!Check(p[stc[i]], p[stc[j]]))return false; } } return true; } inline void Dfs(int step) { if(step == ans + 1) { if(Judge()) { ans1++, ans2 += sc; if(ans1 > Mod) ans1 -= Mod; if(ans2 > Mod) ans2 -= Mod; } return; } stc[++sc] = step; Dfs(step + 1); --sc; Dfs(step + 1); } // /hsh signed main() { // return system("fc ex_tree2.out ans.out"), 0; // freopen("tree.in", "r", stdin); // freopen("tree.out", "w", stdout); n = read(), type = read(); for(int i = 1; i <= n - 1; i++) { int u = read(), v = read(); add_edge(u, v), add_edge(v, u); } dfs(1, 0); Sub2::Main(); Dfs(1); cout << ans1 % Mod << '\n'; if(type == 1) cout << ans2 % Mod << '\n'; return 0; }
D
// Start:10:10 Finish: 10:28 Score:20pts #include <bits/stdc++.h> #define pb push_back #define lson rt << 1 #define rson rt << 1 | 1 using namespace std; const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; inline int read() { int res = 0, f = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) f |= (ch == '-'); for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch - '0'); return f ? -res : res; } int dis[N]; struct Node { int v, nxt;} e[N]; int n, q, head[N], num_edge = 0, top[N], son[N], fa[N], siz[N], dep[N]; inline void add_edge(int u, int v) { e[++num_edge] = (Node) {v, head[u]}, head[u] = num_edge;} inline void dfs1(int u, int Fa, int w) { fa[u] = Fa, dep[u] = dep[Fa] + 1, siz[u] = 1, dis[u] = dis[Fa] + w; for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if(v == Fa) continue; dfs1(v, u, 1); siz[u] += siz[v]; if(siz[son[u]] < siz[v]) son[u] = v; } } inline void dfs2(int u, int tp) { top[u] = tp; if(son[u]) dfs2(son[u], tp); for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if(v == fa[u] || v == son[u]) continue; dfs2(v, v); } } inline int LCA(int x, int y) { while(top[x] ^ top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x, y); x = fa[top[x]]; } return dep[x] < dep[y] ? x : y; } inline int Dis(int x, int y) { int lca = LCA(x, y); return dis[x] + dis[y] - (dis[lca] << 1); } signed main() { // return system("fc ex_atree2.out ans.out"), 0; freopen("atree.in", "r", stdin); freopen("atree.out", "w", stdout); n = read(), q = read(); for(int i = 1; i <= n - 1; i++) { int u = read(), v = read(); add_edge(u, v), add_edge(v, u); } dfs1(1, 0, 0), dfs2(1, 0); while(q--) { int u = read(), v = read(), d = read(); int ans = 0; for(int i = 1; i <= n; i++) { ans += (Dis(u, i) <= d || Dis(v, i) <= d); } cout << ans, putchar('\n'); } return 0; }
本文作者:TLE_Automation
本文链接:https://www.cnblogs.com/tttttttle/p/16904965.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现