[{"content":"CSUST ACMore Evening training 2024.12.1 Problem1 我们可以推一下这个式子就可以发现题目要我们求啥，目要去掉俩个数后算术平均数相等，那我们就选俩个去掉假设为 $a_x, a_y$ $\\frac{Sum}{n} = \\frac{Sum - a_x-a_y}{n - 2}$ $得到： 2 \\times Sum = (a_x + a_y) \\times n $ 我们会发现如果 $2 \\times Sum \\equiv 0 (\\bmod n)$ 才可能存在有解，然后就是需要存在 $(a_x+a_y) = \\frac{2\\times Sum}{n}$ ，令 $w = \\frac{2\\times Sum}{n}$，假设 $x \u0026lt; y$ 要求的就是对于每一个 $y$ 有多少个 $x$ 满足 $x \u0026lt; y 且 a_x = w - a_y$ 我们发现只要从前往后按顺序遍历，再求一下之前有多少个 $w - a_y$ 即可，可以用个 $map$ 记录，直接遍历就好\nProblem2 给定一个字符串 $s$ 以及一个字符 $c$ 需要进行一些操作，将这个字符串所有位置变成这个字符，每一次操作是选择一个值 $x$ 把所有不是 $x$ 倍数的位置修改成 $c$ ，我们可以分类讨论一下\n首先是 $0$ 次，如果 $s$ 每一位都是 $c$ 那么修改次数显然是 $0$ 次\n然后是 $1$ 次，我们可以枚举 $1 \\sim n$ 每个数 $i$ 的倍数，然后如果对于 $i$ 的倍数位置，不存在与 $c$ 不相同的位置，那么我们就可以选择这个数，然后一次修改完毕，复杂度参考 埃氏筛 ，大致为 $O(nloglogn)$ 时间是够的\n然后就是剩下的全部可以 $2$ 次操作完，细想一下，我们怎么构造，其实只需要 $n$ 和 $n - 1$ 这俩个数即可，因为 $n$ 的倍数是它自己，其他位置都可以修改，然后 $2 * (n-1) \u0026gt; n$ 是显然的（题目保证 $n \\ge 3$ ）那么就做完了\nProblem3 模拟删点的过程即可，每个点最多被删一次，每次删的点是度为 $1$ 的点，然后我们做类似与拓扑排序的一个过程，每次删掉一层，把这些删掉的点，连接的另外一些点的度减掉，如果度变成一了就放入，不过需要暂时存下来，因为每次是删一层，然后注意一下边界情况的特判就行了\nProblem4 按照题意模拟即可，首先能删除的是 $1$ 个节点，接下来是 $2, 4, 8, 16$ ，对于每一步是 $2^{i-1}$，直到达到 $2^{i-1} \\ge q$ ，对于$2^{i-1} \u0026lt; q$ 只需要每次加上$1$ 即可，到 $2^{i-1}\\ge q$ 时我们发现，只要一层一层删，我们每次都能删掉 $q$ 个节点，剩下的节点个数为 $x$，那么还需要操作 $\\lceil \\frac{x}{q} \\rceil$ 次，这样就欧拉\n","permalink":"/posts/acm/1/","summary":"CSUST ACMore Evening training 2024.12.1 Problem1 我们可以推一下这个式子就可以发现题目要我们求啥，目要去掉俩个数后算术平均数相等，那我们就选俩个去掉假设为 $a_x, a_y$ $\\frac{Sum}{n} = \\frac{Sum - a_x-a_y}{n - 2}$ $得到： 2 \\times Sum = (a_x + a_y) \\times n $ 我们会发现如果 $2 \\times Sum \\equiv 0 (\\bmod n)$ 才可能存在有解，然后就是需要存在 $(a_x+a_y) = \\frac{2\\times Sum}{n}$ ，令 $w = \\frac{2\\times Sum}{n}$，假设 $x \u0026lt; y$ 要求的就是对","title":"CSUST ACMore Evening training 2024.12.1"},{"content":"A. Turtle Puzzle: Rearrange and Negate 因为可以任意排列这个数组，并将一段区间内的数乘 $-1$，我们可以排序后把所有负数变为正数，即可\n$code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; int ans = 0; for(int i = 0, x; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; x; ans += std::abs(x); } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B. Turtle Math: Fast Three Task 分类讨论，$\\sum_{i=1}^na_i\\mod 3$ 等于 $0$ 的话不需要操作，等于 $1$ 就看有没有 $\\mod 3 \\equiv 1$ 的数，有得话删掉，没有的话就对一个数 $+2$ 即可，等于 $2$ 的话直接对一个数 $+1$ 即可\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::array\u0026lt;int, 3\u0026gt; cnt{}; for(int i = 0; i \u0026lt; n; i ++ ) { int x; std::cin \u0026gt;\u0026gt; x; cnt[x % 3] ++; } int o = (cnt[1] + 2 * cnt[2]) % 3; if(o == 0) { std::cout \u0026lt;\u0026lt; 0 \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } else if(o == 1) { if(cnt[1]) { std::cout \u0026lt;\u0026lt; 1 \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } else { std::cout \u0026lt;\u0026lt; 2 \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } } else { std::cout \u0026lt;\u0026lt; 1 \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } } C. Turtle Fingers: Count the Values of k 观察到 $x, y$ 的范围不会很大于是乎我们枚举 $x, y$ 然后统计 $k$ 的种类数即可\nvoid solve() { int a, b, l; std::cin \u0026gt;\u0026gt; a \u0026gt;\u0026gt; b \u0026gt;\u0026gt; l; std::set\u0026lt;int\u0026gt; S; for(int i = 1; i \u0026lt;= l; i *= a) { for(int j = 1; j \u0026lt;= l; j *= b) { if(1LL * i * j \u0026lt;= l) { if(l % (i * j) == 0) { S.insert(l / (i * j)); } } } } std::cout \u0026lt;\u0026lt; S.size() \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } D. Turtle Tenacity: Continual Mods 暂时不会证明，有排序讨论的做法，我的写法是判断整个数组的 $gcd$ 出现了多少次，不超过 $1$ 次即可\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; int g = 0; std::vector\u0026lt;int\u0026gt; a(n); for(int i = 0; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; g = std::gcd(g, a[i]); } int cnt = 0; for(int i = 0; i \u0026lt; n; i ++ ) { if(g == a[i]) { cnt ++; } } std::cout \u0026lt;\u0026lt; (cnt \u0026gt; 1 ? \u0026#34;NO\u0026#34; : \u0026#34;YES\u0026#34;) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } E. Turtle vs. Rabbit Race: Optimal Trainings 我们找到总 $l$ 出发然后场数 $\\ge u$ 的位置，之后的数全是负数不可取，然后当前位置也有可能包含负数，我们与前一个位置比较一下大小即可得到答案，找到这个位置可以用前缀和＋二分来求\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::vector\u0026lt;i64\u0026gt; a(n + 1); for(int i = 1; i \u0026lt;= n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; a[i] += a[i - 1]; } auto get = [\u0026amp;](int l, int r, int u) -\u0026gt; i64 { i64 n = a[r] - a[l - 1]; return 1LL * u * n - 1LL * (n - 1) * n / 2; }; auto fid = [\u0026amp;](int l, int v) -\u0026gt; int { int r = n; while(l \u0026lt; r) { int mid = l + r \u0026gt;\u0026gt; 1; if(a[mid] \u0026gt;= v) r = mid; else l = mid + 1; } return r; }; int q; std::cin \u0026gt;\u0026gt; q; while(q -- ) { int l, u; std::cin \u0026gt;\u0026gt; l \u0026gt;\u0026gt; u; int p = fid(l, a[l - 1] + u + 1); // int p = std::lower_bound(a.begin() + l, a.end(), a[l - 1] + u + 1) - a.begin(); if(p == l) { std::cout \u0026lt;\u0026lt; l \u0026lt;\u0026lt; \u0026#39; \u0026#39;; } else { i64 v1 = get(l, p, u), v2 = get(l, p - 1, u); std::cout \u0026lt;\u0026lt; (v1 \u0026gt; v2 ? p : p - 1) \u0026lt;\u0026lt; \u0026#39; \u0026#39;; } } std::cout \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } F. Turtle Mission: Robot and the Earthquake 我们可以将地图的运动转换为人物的相对运动，于是就得到了三种运动方式 $(x,y),(x+2,y),(x+1,y+1)$ ，然后观察到答案也会相对运动每次运动 $(x+1,y)$ ，答案可以在边界上移动，我们只要能达到右边界，然后停在原地等答案到即可，先 $bfs$ 求出到边界的最短路，然后加上需要等待答案过来的时间即可\nint n, m; std::cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; m; std::vector\u0026lt;std::vector\u0026lt;int\u0026gt;\u0026gt; g(n, std::vector\u0026lt;int\u0026gt;(m)); for(int i = 0; i \u0026lt; n; i ++ ) { for(int j = 0; j \u0026lt; m; j ++ ) { std::cin \u0026gt;\u0026gt; g[i][j]; } } std::vector\u0026lt;std::vector\u0026lt;int\u0026gt;\u0026gt; d(n, std::vector\u0026lt;int\u0026gt;(m, -1)); std::queue\u0026lt;std::pair\u0026lt;int, int\u0026gt;\u0026gt; q; q.push({0, 0}); d[0][0] = 0; auto ok = [\u0026amp;](int x, int y) -\u0026gt; bool { return !g[x][y]; }; while(!q.empty()) { auto [x, y] = q.front(); q.pop(); if(ok((x + 1) % n, y) \u0026amp;\u0026amp; ok((x + 2) % n, y) \u0026amp;\u0026amp; d[(x + 2) % n][y] == -1) { d[(x + 2) % n][y] = d[x][y] + 1; q.push({(x + 2) % n, y}); } if(ok((x + 1) % n, (y + 1) % m) \u0026amp;\u0026amp; d[(x + 1) % n][(y + 1) % m] == -1) { d[(x + 1) % n][(y + 1) % m] = d[x][y] + 1; q.push({(x + 1) % n, (y + 1) % m}); } } int ans = 1e9; for(int i = 0; i \u0026lt; n; i ++ ) { if(d[i][m - 1] != -1) { int x = d[i][m - 1] % n, y = (i + 1) % n; ans = std::min(ans, d[i][m - 1] + (y - x + n) % n); } } std::cout \u0026lt;\u0026lt; (ans == 1e9 ? -1 : ans) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } ","permalink":"/posts/acm/codeforces-round-929-div.-3/","summary":"A. Turtle Puzzle: Rearrange and Negate 因为可以任意排列这个数组，并将一段区间内的数乘 $-1$，我们可以排序后把所有负数变为正数，即可 $code:$ void solve() { int n; std::cin \u0026gt;\u0026gt; n; int ans = 0; for(int i = 0, x; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; x; ans += std::abs(x); } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B. Turtle Math: Fast Three Task 分类讨论，$\\sum_{i=1}^na_i\\mod 3$ 等于 $0$ 的话不需要操作，等于 $1$ 就看有","title":"Codeforces Round 929 (Div. 3)"},{"content":"A.小红的 01 背包 能装多少装多少就行\n$code:$\nvoid solve() { int v, x, y; std::cin \u0026gt;\u0026gt; v \u0026gt;\u0026gt; x \u0026gt;\u0026gt; y; std::cout \u0026lt;\u0026lt; v / x * y \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B.小红的 dfs 枚举每一行，然后对于第一行为 $dfs$ 的情况, 只存在第一列也为 $dfs$ 满足，其他行同理枚举一遍即可\nvoid solve() { char g[3][3]; for(int i = 0; i \u0026lt; 3; i ++) { for(int j = 0; j \u0026lt; 3; j ++ ) { std::cin \u0026gt;\u0026gt; g[i][j]; } } int ans = 9, v = 0; if(g[0][0] != \u0026#39;d\u0026#39;) v ++; if(g[0][1] != \u0026#39;f\u0026#39;) v ++; if(g[0][2] != \u0026#39;s\u0026#39;) v ++; if(g[1][0] != \u0026#39;f\u0026#39;) v ++; if(g[2][0] != \u0026#39;s\u0026#39;) v ++; ans = std::min(ans, v); v = 0; if(g[1][0] != \u0026#39;d\u0026#39;) v ++; if(g[1][1] != \u0026#39;f\u0026#39;) v ++; if(g[1][2] != \u0026#39;s\u0026#39;) v ++; if(g[0][1] != \u0026#39;d\u0026#39;) v ++; if(g[2][1] != \u0026#39;s\u0026#39;) v ++; ans = std::min(ans, v); v = 0; if(g[2][0] != \u0026#39;d\u0026#39;) v ++; if(g[2][1] != \u0026#39;f\u0026#39;) v ++; if(g[2][2] != \u0026#39;s\u0026#39;) v ++; if(g[0][2] != \u0026#39;d\u0026#39;) v ++; if(g[1][2] != \u0026#39;f\u0026#39;) v ++; ans = std::min(ans, v); std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } C.小红的排列生成 先将其排序, 然后构造排列 $1, 2, 3, \u0026hellip;, n$ , 统计代价即可\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::vector\u0026lt;int\u0026gt; a(n); for(int i = 0; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; } std::sort(a.begin(), a.end()); i64 s = 0; for(int i = 0; i \u0026lt; n; i ++ ) { s += std::abs(a[i] - i - 1); } std::cout \u0026lt;\u0026lt; s \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } D.小红的二进制树 由题意, 从一点往子节点走，要其形成的二进制数为奇数，即最后一位为1, 故统计子树中的一的个数即可\nvoid solve() { int n; std::string s; std::cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; s; std::vector\u0026lt;int\u0026gt; w(n); for(int i = 0; i \u0026lt; n; i ++ ) { w[i] = s[i] - \u0026#39;0\u0026#39;; } auto c = w; std::vector\u0026lt;std::vector\u0026lt;int\u0026gt;\u0026gt; adj(n); for(int i = 0; i \u0026lt; n - 1; i ++ ) { int u, v; std::cin \u0026gt;\u0026gt; u \u0026gt;\u0026gt; v; u --, v --; adj[u].push_back(v); adj[v].push_back(u); } auto dfs = [\u0026amp;](auto self, int u, int fa) -\u0026gt; void { for(auto v : adj[u]) { if(v != fa) { self(self, v, u); w[u] += w[v]; } } }; dfs(dfs, 0, -1); for(int i = 0; i \u0026lt; n; i ++ ) { std::cout \u0026lt;\u0026lt; w[i] - c[i] \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } } E.小红的回文数 我们对每一个数的出现次数为奇数还是偶数进行状态统计, $0$ 表示为偶数, $1$ 表示为奇数, 总共有 $10$ 个数, 我们只需要用一个 $2^{10}$ 的数即可统计其状态, 然后能构造成回文串的话, 当且仅当只有一位为 $1$ 或者全为 $0$, 然后我们记录之前的状态, 然后我们从前往后统计, 选择当前位置 $i$, 然后枚举前面位置 $j$ , 只需要 $i$ 的状态与 $j$ 的状态相同或只有 $1$ 位有区别即可, 枚举肯定超时, 开一个桶记录即可, 然后计算贡献\nvoid solve() { std::map\u0026lt;int, int\u0026gt; mp; mp[0] = 1; std::string s; std::cin \u0026gt;\u0026gt; s; i64 ans = 0, st = 0; for(int i = 0, n = s.size(); i \u0026lt; n; i ++ ) { int v = s[i] - \u0026#39;0\u0026#39;; st ^= (1 \u0026lt;\u0026lt; v); for(int j = 0; j \u0026lt; 10; j ++ ) { ans += mp[st ^ (1 \u0026lt;\u0026lt; j)]; } ans += mp[st]; mp[st] ++; } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } F.小红的矩阵修改 观察到 $n$ 非常的小, 每一位也就只有三种情况, 这很容易想到状压$dp$, 枚举每一位填什么即可, 复杂度也不高\nvoid solve() { int n, m; std::cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; m; std::vector\u0026lt;std::vector\u0026lt;char\u0026gt;\u0026gt; g(n, std::vector\u0026lt;char\u0026gt;(m)); for(int i = 0; i \u0026lt; n; i ++ ) { for(int j = 0; j \u0026lt; m; j ++ ) { std::cin \u0026gt;\u0026gt; g[i][j]; if(g[i][j] == \u0026#39;r\u0026#39;) g[i][j] = 0; if(g[i][j] == \u0026#39;e\u0026#39;) g[i][j] = 1; if(g[i][j] == \u0026#39;d\u0026#39;) g[i][j] = 2; } } auto check = [\u0026amp;](const std::vector\u0026lt;int\u0026gt; \u0026amp;o) -\u0026gt; bool { for(int i = 1; i \u0026lt; n; i ++ ) { if(o[i] == o[i - 1]) { return false; } } return true; }; // std::vector\u0026lt;std::vector\u0026lt;int\u0026gt;\u0026gt; st; // for(int i = 0, r = pow(3, n); i \u0026lt; r; i ++ ) { int k = i; std::vector\u0026lt;int\u0026gt; v; while(k) { v.push_back(k % 3); k /= 3; } while(v.size() \u0026lt; n) v.push_back(0); std::reverse(v.begin(), v.end()); if(check(v)) { st.push_back(v); } } auto get = [\u0026amp;](int pos, const std::vector\u0026lt;int\u0026gt; \u0026amp;a) -\u0026gt; int { int cnt = 0; for(int i = 0; i \u0026lt; n; i ++ ) { if(a[i] != g[i][pos]) { cnt ++; } } return cnt; }; auto ok = [\u0026amp;](const std::vector\u0026lt;int\u0026gt; \u0026amp;a, const std::vector\u0026lt;int\u0026gt; \u0026amp;b) -\u0026gt; int { for(int i = 0; i \u0026lt; n; i ++ ) { if(a[i] == b[i]) { return false; } } return true; }; // 3 ^ 4 std::map\u0026lt;std::vector\u0026lt;int\u0026gt;, i64\u0026gt; dp, _dp; for(auto v : st) { dp[v] = get(0, v); } for(int i = 1; i \u0026lt; m; i ++ ) { _dp.clear(); for(auto [x, y] : dp) { for(auto v : st) { int w = get(i, v); if(ok(x, v)) { if(!_dp.count(v)) { _dp[v] = y + w; } else { _dp[v] = std::min(_dp[v], y + w); } } } } dp = _dp; } i64 ans = 1e9; for(auto [x, y] : dp) { ans = std::min(ans, y); } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } ","permalink":"/posts/acm/%E7%89%9B%E5%AE%A2%E5%91%A8%E8%B5%9Bround32/","summary":"A.小红的 01 背包 能装多少装多少就行 $code:$ void solve() { int v, x, y; std::cin \u0026gt;\u0026gt; v \u0026gt;\u0026gt; x \u0026gt;\u0026gt; y; std::cout \u0026lt;\u0026lt; v / x * y \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B.小红的 dfs 枚举每一行，然后对于第一行为 $dfs$ 的情况, 只存在第一列也为 $dfs$ 满足，其他行同理枚举一遍即可 void solve() { char g[3][3]; for(int i = 0; i \u0026lt; 3; i ++) { for(int j = 0; j \u0026lt; 3; j ++ ) { std::cin \u0026gt;\u0026gt; g[i][j]; } } int ans = 9, v = 0; if(g[0][0] != \u0026#39;d\u0026#39;) v ++; if(g[0][1] != \u0026#39;f\u0026#39;) v ++; if(g[0][2] !=","title":"牛客周赛Round32"},{"content":"A. Tricky Template 我们对每个位置 $i$ 来看,只要 $a_i == c_i \\ or \\ b_i == c_i$​ ,那么就会使其不成立, 如果是整个字符串呢，那么就是，那么就需要每个位置都成立才能使其不成立，于是遍历判断一下即可\n$code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::string a, b, c; std::cin \u0026gt;\u0026gt; a \u0026gt;\u0026gt; b \u0026gt;\u0026gt; c; int ok = 0; for(int i = 0; i \u0026lt; n; i ++ ) { if(a[i] != c[i] \u0026amp;\u0026amp; b[i] != c[i]) { ok = 1; } } std::cout \u0026lt;\u0026lt; (ok ? \u0026#34;YES\u0026#34; : \u0026#34;NO\u0026#34;) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B. Forming Triangles 首先题目给的 长度是 $2^{a_i}$ ,我们观察一下，发现能构成三角形的边长只有这种情况 $(2^n, 2^n, 2^k) (其中 k \\le n)$ ，那么我们就直接计数即可，特判一下 $k == n$ 的情况，我们计算贡献，记录 $2^n$ 的个数为x, 小于 $2^n$ 的个数为 $s$，对于 $k == n: \\tbinom{x}{3}$ , 对于 $k \u0026lt; n:\\tbinom{x}{2} * s$，求个前缀和统计贡献即可\n$code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::map\u0026lt;int, int\u0026gt; mp; for(int i = 0; i \u0026lt; n; i ++ ) { int x; std::cin \u0026gt;\u0026gt; x; mp[x] ++; } o i64 ans = 0, s = 0; for(auto [x, y] : mp) { if(y \u0026gt;= 3) { ans += 1LL * y * (y - 1) * (y - 2) / 3 / 2; } if(y \u0026gt;= 2) { ans += 1LL * y * (y - 1) / 2 * s; } s += y; } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } C. Closest Cities 我们分别记录从 $1$ 走到 $i$ 的代，以及从 $n$ 走到 $i$ 的代价，就是一个前缀和后缀，然后判断一下每个路径的取值，最后查询就减去即可\n$code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::vector\u0026lt;int\u0026gt; a(n); for(int i = 0; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; } std::vector\u0026lt;i64\u0026gt; pre(n), suf(n); pre[1] = 1; for(int i = 1; i \u0026lt; n - 1; i ++ ) { pre[i + 1] = pre[i] + (a[i + 1] - a[i] \u0026lt; a[i] - a[i - 1] ? 1 : a[i + 1] - a[i]); } suf[n - 2] = 1; for(int i = n - 2; i \u0026gt;= 1; i -- ) { suf[i - 1] = suf[i] + (a[i] - a[i - 1] \u0026lt; a[i + 1] - a[i] ? 1 : a[i] - a[i - 1]); } int q; std::cin \u0026gt;\u0026gt; q; while(q -- ) { int x, y; std::cin \u0026gt;\u0026gt; x \u0026gt;\u0026gt; y; x --, y --; if(x \u0026lt; y) { std::cout \u0026lt;\u0026lt; pre[y] - pre[x] \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } else { std::cout \u0026lt;\u0026lt; suf[y] - suf[x] \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } } } D. Berserk Monsters 观察到如果一个怪兽被消灭，那么受影响的只有与之相邻的俩个怪兽，其余的都不会改变，链表模拟这个过程即可，设每次删除的怪兽为$x_i$ 那么 复杂度大致为 $2(x_1 + x_2+\u0026hellip;+x_n) = 2n$ ，然后可以用 $set$ 去维护，多一个 $log(n)$ 的复杂度，总复杂度为 $O(nlogn)$\n$code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::vector\u0026lt;int\u0026gt; a(n + 2), d(n + 2), l(n + 2), r(n + 2), del(n + 2); for(int i = 1; i \u0026lt;= n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; } for(int i = 1; i \u0026lt;= n; i ++ ) { std::cin \u0026gt;\u0026gt; d[i]; } std::queue\u0026lt;int\u0026gt; q, _q; for(int i = 1; i \u0026lt;= n; i ++ ) { r[i] = i + 1; l[i] = i - 1; q.push(i); } l[n + 1] = n; r[0] = 1; std::vector\u0026lt;int\u0026gt; ans; for(int i = 0; i \u0026lt; n; i ++ ) { std::queue\u0026lt;int\u0026gt; _q; while(!q.empty()) { int pos = q.front(); q.pop(); int v = a[l[pos]] + a[r[pos]]; if(v \u0026gt; d[pos]) { _q.push(pos); } } std::set\u0026lt;int\u0026gt; S; ans.push_back(_q.size()); while(!_q.empty()) { auto u = _q.front(); _q.pop(); del[u] = true; if(l[u] \u0026gt;= 1 \u0026amp;\u0026amp; l[u] \u0026lt;= n) S.insert(l[u]); if(r[u] \u0026gt;= 1 \u0026amp;\u0026amp; r[u] \u0026lt;= n) S.insert(r[u]); r[l[u]] = r[u]; l[r[u]] = l[u]; } for(auto x : S) { if(!del[x]) { q.push(x); } } } for(auto x : ans) { std::cout \u0026lt;\u0026lt; x \u0026lt;\u0026lt; \u0026#39; \u0026#39;; } std::cout \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } ","permalink":"/posts/acm/educational-codeforces-round-161-rated-for-div.-2/","summary":"A. Tricky Template 我们对每个位置 $i$ 来看,只要 $a_i == c_i \\ or \\ b_i == c_i$​ ,那么就会使其不成立, 如果是整个字符串呢，那么就是，那么就需要每个位置都成立才能使其不成立，于是遍历判断一下即可 $code:$ void solve() { int n; std::cin \u0026gt;\u0026gt; n; std::string a, b, c; std::cin \u0026gt;\u0026gt; a \u0026gt;\u0026gt; b \u0026gt;\u0026gt; c; int ok = 0; for(int i = 0; i \u0026lt; n; i ++ ) { if(a[i] != c[i] \u0026amp;\u0026amp; b[i] != c[i]) { ok = 1; } } std::cout \u0026lt;\u0026lt; (ok ? \u0026#34;YES\u0026#34; : \u0026#34;NO\u0026#34;)","title":"Educational Codeforces Round 161 (Rated for Div. 2) A-E"},{"content":"牛客周赛Round31 A.小红小紫替换 判断即可\n$code:$\nvoid solve() { std::string s; std::cin \u0026gt;\u0026gt; s; std::cout \u0026lt;\u0026lt; (s == \u0026#34;kou\u0026#34; ? \u0026#34;yukari\u0026#34; : s) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B.小红的因子数 看到数据范围为 $1e13$，$\\sqrt{1e13} \\approx 3e6$ 所以直接枚举根号以内的素因子即可\n复杂度 $O(\\sqrt{n})$\n$code:$\nvoid solve() { i64 x; std::cin \u0026gt;\u0026gt; x; int ans = 0; for(int i = 2; i \u0026lt;= x / i; i ++ ) { if(x % i == 0) { while(x % i == 0) { x /= i; } ans ++; } } ans += x \u0026gt; 1; std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } C.小红的字符串中值 首先观察到，中值左右俩边的字符数量一定相等，然后我们只需要枚举$S$中每一个等于询问字符的位置，然后计算左右两边能取到多少即可\nvoid solve() { int n; char o; std::cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; o; std::string s; std::cin \u0026gt;\u0026gt; s; i64 ans = 0; for(int i = 0; i \u0026lt; n; i ++ ) { if(s[i] == o) { i64 l = i, r = n - i - 1; ans += std::min(l, r) + 1; } } std::cout \u0026lt;\u0026lt; ans \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } D.小红数组操作 模拟链表即可，每个数维护一个节点，记录左右相连的值，模拟操作\nvoid solve() { int q; std::cin \u0026gt;\u0026gt; q; std::map\u0026lt;int, int\u0026gt; l, r; r[0] = -1; int siz = 0; while(q -- ) { int op, x, y; std::cin \u0026gt;\u0026gt; op; if(op == 1) { std::cin \u0026gt;\u0026gt; x \u0026gt;\u0026gt; y; r[x] = r[y]; l[x] = y; l[r[y]] = x; r[y] = x; siz ++; } else { std::cin \u0026gt;\u0026gt; x; r[l[x]] = r[x]; l[r[x]] = l[x]; siz --; } } std::cout \u0026lt;\u0026lt; siz \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; int now = r[0]; while(now != -1) { std::cout \u0026lt;\u0026lt; now \u0026lt;\u0026lt; \u0026#39; \u0026#39;; now = r[now]; } } E.小红数组操作 因为数据范围比较小，我们能想到 $dp$，我们定义 $dp_i$ 表示的是所有元素和为 $i$ 时选择的元素数量最小为多少，对于每个数字有选和不选俩种情况，记录选择上一位选完的状态为 $dp$ ，当前位的状态为 $_dp$ ，当前状态能由上一位推出，并且没有影响，我们枚举上一位有的情况，然后对于 $a_i$ 选和不选俩种情况更新 $_dp$，实际上就是滚动数组，也可以记录位置，用二维 $dp$ ，同理 $$ 选：_dp[i - a[pos]] = std::min(_dp[i - a[pos]], dp[i] + 1) \\newline 不选：_dp[i + a[pos]] = std::min(_dp[i + a[pos]], dp[i]); \\newline 注意：这里如果 _dp 中没有这个元素就直接更新 $$ $code:$\nvoid solve() { int n; std::cin \u0026gt;\u0026gt; n; std::vector\u0026lt;int\u0026gt; a(n); for(int i = 0; i \u0026lt; n; i ++ ) { std::cin \u0026gt;\u0026gt; a[i]; } std::map\u0026lt;int, int\u0026gt; dp; dp[0] = 0; for(int i = 0; i \u0026lt; n; i ++ ) { std::map\u0026lt;int, int\u0026gt; _dp; for(auto [v, y] : dp) { if(!_dp.count(v - a[i])) { _dp[v - a[i]] = y + 1; } else { _dp[v - a[i]] = std::min(_dp[v - a[i]], y + 1); } if(!_dp.count(v + a[i])) { _dp[v + a[i]] = y; } else { _dp[v + a[i]] = std::min(_dp[v + a[i]], y); } } dp = _dp; } std::cout \u0026lt;\u0026lt; (dp.count(0) ? dp[0] : -1) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } F.小红的连续段 $code:$\nvoid solve() { int x, y; std::cin \u0026gt;\u0026gt; x \u0026gt;\u0026gt; y; static constexpr int P = 1e9 + 7; std::vector\u0026lt;i64\u0026gt; fac(1001), invfac(1001), inv(1001); fac[0] = invfac[0] = fac[1] = invfac[1] = inv[1] = 1; for(int i = 2; i \u0026lt;= 1000; i ++ ) { inv[i] = (P - P / i * inv[P % i] % P) % P; fac[i] = fac[i - 1] * i % P; invfac[i] = invfac[i - 1] * inv[i] % P; } auto C = [\u0026amp;](i64 n, i64 m) -\u0026gt; i64 { if(m \u0026gt; n) return 0; return fac[n] * invfac[n - m] % P * invfac[m] % P; }; std::vector\u0026lt;i64\u0026gt; ans(x + y + 1); for(int i = 1; i \u0026lt;= x - 1; i ++ ) { ans[2 * i + 1] = (ans[2 * i + 1] + C(x - 1, i) * C(y - 1, i - 1) % P) % P; } for(int i = 0; i \u0026lt;= x - 1; i ++ ) { ans[2 * i + 2] = (ans[2 * i + 2] + C(x - 1, i) * C(y - 1, i) % P) % P; } for(int i = 1; i \u0026lt;= y - 1; i ++ ) { ans[2 * i + 1] = (ans[2 * i + 1] + C(y - 1, i) * C(x - 1, i - 1) % P) % P; } for(int i = 0; i \u0026lt;= x - 1; i ++ ) { ans[2 * i + 2] = (ans[2 * i + 2] + C(y - 1, i) * C(x - 1, i) % P) % P; } for(int i = 1; i \u0026lt;= x + y; i ++ ) { std::cout \u0026lt;\u0026lt; ans[i] \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } } ","permalink":"/posts/acm/%E7%89%9B%E5%AE%A2%E5%91%A8%E8%B5%9Bround31/","summary":"牛客周赛Round31 A.小红小紫替换 判断即可 $code:$ void solve() { std::string s; std::cin \u0026gt;\u0026gt; s; std::cout \u0026lt;\u0026lt; (s == \u0026#34;kou\u0026#34; ? \u0026#34;yukari\u0026#34; : s) \u0026lt;\u0026lt; \u0026#39;\\n\u0026#39;; } B.小红的因子数 看到数据范围为 $1e13$，$\\sqrt{1e13} \\approx 3e6$ 所以直接枚举根号以内的素因子即可 复杂度 $O(\\sqrt{n})$ $code:$ void solve() { i64 x; std::cin \u0026gt;\u0026gt; x; int ans = 0; for(int i = 2; i \u0026lt;= x / i; i ++ ) { if(x % i == 0) { while(x % i == 0) { x /=","title":"牛客周赛Round31"},{"content":"组合数学 排列与组合 1.帕斯卡公式 $$ 对于所有满足 1\\le k \\le n-1的整数 n 和 k,有 \\newline \\tbinom{n}{k} = \\tbinom{n - 1}{k} + \\tbinom{n - 1}{k - 1} $$\n2.定理 $$ 1. 设多重集合S，有k种类型对象，每一种类型的有限出现次数时n_1,n_2,\u0026hellip;,n_k,设S的大小为 n, S的排列数为 \\newline \\frac{n!}{n_1!n_2!\u0026hellip;n_k!} \\newline 2.设S为有k种类型的多重集合,每种元素有无限个,S的r组合个数等于 \\newline \\tbinom{r+k-1}{r} $$\n","permalink":"/posts/acm/%E7%BB%84%E5%90%88%E6%95%B0%E5%AD%A6/","summary":"组合数学 排列与组合 1.帕斯卡公式 $$ 对于所有满足 1\\le k \\le n-1的整数 n 和 k,有 \\newline \\tbinom{n}{k} = \\tbinom{n - 1}{k} + \\tbinom{n - 1}{k - 1} $$ 2.定理 $$ 1. 设多重集合S，有k种类型对象，每一种类型的有限出现次数时n_1,n_2,\u0026hellip;,n_k,设S的大小为 n, S的排列数为 \\newline \\frac{n!}{n_1!n_2!\u0026hellip;n_k!} \\newline 2.设S为有k种类型的多重集合,每种元","title":"组合数学"},{"content":"hello $$ \\frac{a_i^{j}}{n} $$\n","permalink":"/posts/acm/blog/","summary":"hello $$ \\frac{a_i^{j}}{n} $$","title":"Blog"},{"content":" \u0026lt; friend name=\u0026ldquo;Sulv\u0026rsquo;s Blog\u0026rdquo; url=\u0026ldquo;https://www.sulvblog.cn\u0026rdquo; logo=\u0026ldquo;https://www.sulvblog.cn/img/Q.gif\u0026quot; word=\u0026ldquo;一个记录技术、阅读、生活的博客\u0026rdquo; \u0026gt;\n👉友链格式 名称： Sulv\u0026rsquo;s Blog 网址： https://www.sulvblog.cn 图标： https://www.sulvblog.cn/img/Q.gif 描述： 一个记录技术、阅读、生活的博客 👉友链申请要求 秉承互换友链原则、文章定期更新、不能有太多广告、个人描述字数控制在15字内\n👉Hugo博客交流群 787018782\n","permalink":"/links/","summary":"\u0026lt; friend name=\u0026ldquo;Sulv\u0026rsquo;s Blog\u0026rdquo; url=\u0026ldquo;https://www.sulvblog.cn\u0026rdquo; logo=\u0026ldquo;https://www.sulvblog.cn/img/Q.gif\u0026quot; word=\u0026ldquo;一个记录技术、阅读、生活的博客\u0026rdquo; \u0026gt; 👉友链格式 名称： Sulv\u0026rsquo;s Blog 网址： https://www.sulvblog.cn 图标： https://www.sulvblog.cn/img/Q.gif 描述： 一个记录技术、阅读、生活的博客 👉友链申请要求 秉承互换友链原则、文章定期更新、不能有太多广告、个人描述字数控制在15字内 👉Hugo博客交流群 787018782","title":"🤝友链"},{"content":"关于我\n名字: shift 职业: 学生 爱好: 不知道 ","permalink":"/about/","summary":"关于我 名字: shift 职业: 学生 爱好: 不知道","title":"🙋🏻‍♂️关于"}]
