整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


Educational Codeforces Round 114 (Rated for Div. 2)

比赛链接:https://codeforces.com/contest/1574/

前四题过于简单()

后两题有点要命()

A. Regular Bracket Sequences

Problem

Solution

只要求输出 nnn 对合法括号,我们移动一下其中一个右括号即可。

Code

// Problem: A. Regular Bracket Sequences
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/A
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 6, INF = 0x3f3f3f3f;
int n, m, s, t;
ll ans;
int a[maxn];void solve()
{cin >> n;for(int i = 1; i <= n; ++ i) {int cnt1 = n, cnt2 = n;for (int j = 1; j <= 2 * n; ++ j) {if(j == i + 1) {cnt2 -- ;putchar(')');}else {if(cnt1) {cnt1 -- ;putchar('(');}else if(cnt2) {cnt2 -- ;putchar(')');}}} puts("");}
}int main()
{cin >> t;while(t -- ) {solve();}return 0;
}

B. Combinatorics Homework

Problem

Solution

设 sum=a+b+csum=a+b+csum=a+b+c

最多的对数显然就是按照顺序放置,一共有 r=sum−3r = sum-3r=sum−3 对。

最少的对数,我们使用数量较小的两个字母 hack=sum−max⁡{a,b,c}hack=sum-\max\{a,b,c\}hack=sum−max{a,b,c},去将数量最多的字母隔开,一共可以隔开 2×hack+12\times hack+12×hack+1 个相同字母,剩下的必须连在一起,那么最少对数就是 l=sum−2×hack−1l = sum-2 \times hack-1l=sum−2×hack−1

判断 mmm 是否在区间内即可。

Code

// Problem: B. Combinatorics Homework
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 6, INF = 0x3f3f3f3f;
int n, m, s, t;
ll ans;
int a, b, c;void solve()
{cin >> a >> b >> c >> n;int hack = a + b + c - max({a, b, c});int l = a + b + c - 2 * hack - 1;int r = a + b + c - 3;if(l <= n && n <= r)puts("YES");else puts("NO");
}int main()
{cin >> t;while(t -- ) {solve();}return 0;
}

C. Slay the Dragon

Problem

Solution

排序后直接 lower_bound 找到大于等于 xxx 的英雄 pospospos 让他去杀 dragon 即可。

由于我们拥有强化的功能,所以需要判断一下让 pospospos 去杀以及让 pos−1pos-1pos−1 强化之后去杀,谁更便宜即可。

Code

// Problem: C. Slay the Dragon
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
const int maxn = 3e5 + 6, INF = 2e18;
int n, m, s, t;
ll ans;
int a[maxn];void solve()
{cin >> n;int sum = 0;int maxx = -INF;for (int i = 1; i <= n; ++ i) scanf("%lld", &a[i]), sum += a[i];sort(a + 1, a + 1 + n);cin >> m;while(m -- ) {int x, y;scanf("%lld%lld", &x, &y);ll ans = INF;int pos = lower_bound(a + 1, a + 1 + n, x) - a; if(pos != n + 1) {int kill = a[pos];int rem = sum - kill;int res = max(0ll, y - rem);ans = min(ans, res);}if(pos != 1) {int kill = a[pos - 1];int rem = sum - kill;int res = max(0ll, y - (sum - a[pos - 1])) + x - a[pos - 1];ans = min(ans, res);}cout << ans << endl;}
}signed main()
{// cin >> t;t = 1;while(t -- ) {solve();}return 0;
}

D. The Strongest Build

Problem

Solution

首先考虑如何判断某种选择方案是否被 ban,显然可以直接使用 hash 表 map O(1)O(1)O(1) 查询即可。我们将数组用 vector 存入,直接使用 map 判断是否存在这种 vector 即可。

由于输入的 aija_{ij}aij​ 是递增的,考虑暴力搜索,我们可以从最外层选择 cic_ici​ ,即 max⁡{ci},i∈[1,n]\max\{c_i\},i\in [1,n]max{ci​},i∈[1,n] 开始往里 bfsbfsbfs 搜索即可,每次各减一步,一旦找到没有被 ban 的即为最大值。

我们在 bfs 搜索时,我们先判断最优解是否被 ban,若被 ban ,判断最优解的下一层也即某一个 i -- ,判断此时是否被 ban 。但是我们发现 ban 掉的方案 m≤105m\le 10^5m≤105,其实我们直接对所有的被 ban 的选择方案,仅判断他们的下一层即可。

对于限选方案 3 2 3

仅判断它的下一层: 2 2 3, 3 1 3, 3 2 2 即可。

此时时间复杂度为 O(nm)=1×106O(nm)=1\times 10^6O(nm)=1×106

因为从最优解开始,只有最优解以及其下一层的方案均被 ban 掉,才需要看下下一层,那么下一层在被 ban 的列表里也将会判断它的下一层。因此仅判断被 ban 的方案的下一层一定能找到可选的最优值。

Code

// Problem: D. The Strongest Build
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
const int maxn = 2e5 + 6, INF = 0x3f3f3f3f, base = 13331, mod1 = 998244353, mod2 = 1e9 + 7;
int n, m, s, t;
vector <int> a[10], ans, b[maxn];
map <vector <int> , int> mp;void solve()
{cin >> n;for (int i = 0; i < n; ++ i) {int c;scanf("%lld", &c);ans.emplace_back(c - 1);for (int j = 0; j < c; ++ j) {int x;scanf("%lld", &x);a[i].emplace_back(x);}}cin >> m;for (int i = 0; i < m; ++ i) { for (int j = 0; j < n; ++ j) {int x;scanf("%lld", &x);x -- ;b[i].emplace_back(x);}mp[b[i]] = 1;}  if(mp.find(ans) == mp.end()) {for (auto it : ans)cout << it + 1 << ' ';puts("");return ;}int res = 0;for (int i = 0; i < m; ++ i) {int sum = 0;for (int j = 0; j < n; ++ j)sum += a[j][b[i][j]];for (int j = 0; j < n; ++ j) {sum -= a[j][b[i][j]];if(b[i][j] == 0) continue;b[i][j] -- ;sum += a[j][b[i][j]];if(mp.find(b[i]) == mp.end()) if(sum > res) ans = b[i], res = sum;sum -= a[j][b[i][j]];b[i][j] ++ ;sum += a[j][b[i][j]];}}for (auto it : ans)cout << it + 1 << ' ';puts("");
}signed main()
{// cin >> t;t = 1;while(t -- ) {solve();}return 0;
}

E. Coloring

Problem

Solution

官方题解:

为了更好地理解,我们将矩阵替换为 000 和 111 ,并使用带有黑白单元格的矩阵。

首先,让我们考虑如果有两个相邻的相同颜色的水平单元格

例如单元格 (5,5)(5,5)(5,5) 和 (5,6)(5,6)(5,6) 是黑色的矩阵,那么单元格 (4,5),(4,6),(6,5)(4,5),(4,6),(6,5)(4,5),(4,6),(6,5) 和 (6,6)(6,6)(6,6) 必须有相反的颜色(白色);

单元格 (3,5),(3,6),(7,5)(3,5),(3,6),(7,5)(3,5),(3,6),(7,5) 和 (7,6)(7,6)(7,6) 必须是相同的颜色(黑色)等等。 因此,两个相邻的水平单元格生成宽度为 222 的垂直条带。 两个相邻的垂直单元格产生宽度为 222 的水平条带。 如果同时存在水平条带和垂直条带,那么答案是 000,因为它们相互矛盾。也就是说对于一个合法矩阵要么都是垂直条带,要么都是水平条带。

如果在同一行中有两个相同颜色的单元格,并且它们之间的单元格数量是偶数(例如 (2,2)(2,2)(2,2) 和 (2,7)(2,7)(2,7) 之间有四个单元格),那么就有一个垂直的条形图(因为它们之间总是有两个相邻的单元格,它们之间的颜色是相同的)。对于水平条带同样适用。

现在让我们考虑如果有垂直的条带,矩阵是什么样子的。 它看起来像一个 n×mn×mn×m 大小的棋盘,但有些垂直条带的颜色是颠倒的。 如果有水平条带,答案同样正确。

我们如何能快速判断在同一行中有两个相同颜色的细胞,它们之间的细胞数是否为偶数?我们可以在棋盘给矩阵涂上棋盘图案。其中一个细胞在棋盘上有相同颜色的细胞,另一个细胞在棋盘上有相反颜色的细胞。

我们维护下面的信息计算答案即可:

  • 每个彩色细胞的颜色;
  • 包含相同颜色单元格且单元格之间有偶数个单元格的行和列;
  • 包含至少一个彩色单元格的行数和列数(用于计算漂亮矩阵的数目)。

Code

官方题解代码:

#include <bits/stdc++.h>using namespace std;const int MOD = 998244353;
const int N = 1'000'009;int sum (int a, int b) {int res = a + b;if (res < 0) res += MOD;if (res >= MOD) res -= MOD;return res;
}int n, m, k;
map <pair <int, int>, char> c;
int cntr[N][2], cntc[N][2];
int cntx[2];
set <int> badr, badc;
set<int> ur, uc;
int p2[N];void upd2(int pos, int col, int add, int cnt[N][2], set <int> &bad, set<int> &u) {cnt[pos][col] += add;assert(cnt[pos][col] >= 0);if (cnt[pos][0] > 0 && cnt[pos][1] > 0){if (!bad.count(pos))bad.insert(pos);} else {if (bad.count(pos))bad.erase(pos);}if (cnt[pos][0] > 0 || cnt[pos][1] > 0){if (!u.count(pos))u.insert(pos);} else {if (u.count(pos))u.erase(pos);}
}void upd(int x, int y, int t) {int col = (x & 1) ^ (y & 1);if (c.count({x, y})) {int ncol = col ^ c[{x, y}];--cntx[ncol];upd2(x, ncol, -1, cntr, badr, ur);upd2(y, ncol, -1, cntc, badc, uc);c.erase({x, y});}if (t == -1)return;int ncol = col ^ t;++cntx[ncol];upd2(x, ncol, 1, cntr, badr, ur);upd2(y, ncol, 1, cntc, badc, uc);c[{x, y}] = t;
}int main(){p2[0] = 1;for (int i = 1; i < N; ++i)p2[i] = sum(p2[i - 1], p2[i - 1]);scanf("%d%d%d", &n, &m, &k);for (int i = 0; i < k; ++i) {int x, y, t;scanf("%d %d %d", &x, &y, &t);--x, --y;upd(x, y, t);int res = 0;if(badr.size() > 0 && badc.size() > 0) {res = 0;} else if (badr.size() > 0) {assert(m - uc.size() >= 0);res = p2[m - uc.size()];} else if (badc.size() > 0) {assert(n - ur.size() >= 0);res = p2[n - ur.size()];} else {if (ur.size() == 0 && uc.size() == 0)res = sum(sum(p2[n], p2[m]), -2);else {assert(m - uc.size() >= 0);res = sum(res, p2[m - uc.size()]);assert(n - ur.size() >= 0);res = sum(res, p2[n - ur.size()]);if (cntx[0] == 0 || cntx[1] == 0) {assert(cntx[0] != 0 || cntx[1] != 0);res = sum(res, -1);}}}printf("%d\n", res);}return 0;
}

F. Occurrences

Problem

Solution

动态规划做法:

https://codeforces.com/blog/entry/95188

生成函数做法:

设 aia_iai​ 为长度为 iii 的有效子数组的个数。

设 aia_iai​​​ 的生成函数 A(x)=∑i=1∞aixi\displaystyle A(x)=\sum\limits_{i=1}^{\infin}a_ix^iA(x)=i=1∑∞​ai​xi​​​

设生成函数 B(x)B(x)B(x)​​​​ 是构成整个序列 aaa 的方案数,显然构造出长度为 mmm​​ 的序列 aaa​​ 的方案数为: [xm]B(x)[x^m]B(x)[xm]B(x)​​​​

有:

B=1+A+A×A+A×A×A+⋯=∑i=0∞Ai=11−A(x)\displaystyle B=1+A+A\times A+A\times A\times A+\cdots=\sum\limits_{i=0}^{\infin}A^i=\cfrac{1}{1-A(x)}B=1+A+A×A+A×A×A+⋯=i=0∑∞​Ai=1−A(x)1​

多项式求逆计算 11−A(x)\cfrac{1}{1-A(x)}1−A(x)1​ 即可。

Code

Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解相关推荐

  1. Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs

    传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici​个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...

  2. Educational Codeforces Round 114 (Rated for Div. 2)C. Slay the Dragon

    题目链接:Problem - 1574C - Codeforces Recently, Petya learned about a new game "Slay the Dragon&quo ...

  3. Educational Codeforces Round 114 (Rated for Div. 2) 个人题解

    中秋节快乐! A. Regular Bracket Sequences 题意 输出nnn个不同的长度为2n2n2n的合法括号序列. 分析 先输出一个"()()()-"序列. 然后依 ...

  4. 1574D The Strongest Build (Educational Codeforces Round 114 (Rated for Div. 2))

    题意 给定n个从小到大的数组,从每个数组中选出一个下标构成一个序列,但是有m种序列被ban了,要求选出的序列对应的数字和最大且没有被ban. 思路 因为有m个序列被ban了,那么最坏的情况可以假设为最 ...

  5. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  6. Educational Codeforces Round 37 (Rated for Div. 2) 1

    Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...

  7. Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)

    Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...

  8. Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...

  9. Educational Codeforces Round 72 (Rated for Div. 2) D. Coloring Edges dfs树/拓扑找环

    传送门 文章目录 题意: 思路: 题意: 给你一张图,你需要给这个图的边染色,保证如果有环那么这个环内边的颜色不全相同,输出染色方案和用的颜色个数. n,m≤5e3n,m\le5e3n,m≤5e3 思 ...

最新文章

  1. 项目管理利器taiga快速安装
  2. PostgreSQL在何处处理 sql查询之二十一
  3. 【项目管理】Scrum内容整理
  4. python常见数据存储 csv txt pickle
  5. python的应用范围有哪些_Python主要应用场景有哪些?
  6. SpringBoot的@SpringBootApplication注解和其他几个注解
  7. 获取linux详细信息,Linux 获取网口详细信息
  8. 近期在做或要做的实验
  9. c++ 封装的zookeeper库
  10. python 装饰器,登录小练习
  11. response返回中文乱码
  12. Cisco 3550交换机IOS备份(真实设备演示)
  13. 注塑模具设计师要懂得的四个概念
  14. hbuilderx gitee操作教程
  15. CAD2018安装计算机黑屏,简单几步解决cad2019在win10上打不开的问题
  16. 手写JDBC的几个步骤(针对MySQL8.0以上的mysql数据库)
  17. SMDS:交换式多兆位数据服务--网络大典
  18. 马斯克的脑机接口,一块树莓派就能做出来?
  19. 软件新产品开发失败原因分析
  20. Qt QEvent 介绍

热门文章

  1. 初学者必备的数组相关知识点
  2. .net中的IO体系介绍
  3. 深度学习目标检测模型全面综述:Faster R-CNN、R-FCN和SSD
  4. ERP实施完了,为什么还要做MES?
  5. Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例
  6. DevOps与持续交付实践
  7. SpringMVC通过注解在数据库中自动生成表
  8. 小米输掉官司,倒打一耙不如坦然认错
  9. visualVM 安装使用
  10. Flask rst 文档转换为html格式文件