Codeforces Round 982 (Div. 2) 题解
A. Rectangle Arrangement
要计算黑色区域的周长,可以把图形转化为矩形来计算。
code:
1234567891011121314151617181920212223242526272829303132333435363738#include <bits/stdc++.h>#define int long long#define x first#define y second#define endl '\n'using namespace std;const int N = 200010;int T;int n;int a[N];signed main(){ ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> T; while (T--) { cin >> n; int x = 0, y = 0; while (n--) ...
c++读写优化
cin & cout
优点:不需要关注数据类型,使用方便。
缺点:速度比较慢,在面对大量数据时需要关闭同步流以加快速度。
关闭同步流
12ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);
sacnf & printf
优点:速度快。
缺点:写起来相对复杂。
快读 & 快写
以字符的形式进行读入和输出,速度快,使用简单。
快读快写
123456789101112131415161718192021222324252627int read(){ int x = 0, f = 1; //快读 char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' &&a ...
异或线性基
异或线性基
对于一个数组 \(a\),若 \(p\) 是它的一组异或线性基,则
\(p\) 中任意非空子集异或和不为 \(0\)
\(p\) 中每个数的最高位 \(1\) 唯一
\(a\) 中任意元素都可以通过 \(p\) 的子集异或出来
构造方法
贪心法和高斯消元
由于高斯消元构造的异或线性基具有更好的性质,因此使用高斯消元法
例题
Luogu P3812 【模板】线性基
题目描述
给定 \(n\) 个整数(数字可能重复),求在这些数中选取任意个,使得它们的异或和最大。
输入格式
第一行一个数 \(n\),表示元素个数。
接下来一行 \(n\) 个数。
输出格式
仅一行,表示答案。
数据范围
\(1 \leq n \leq 50,\ 0 \leq S_i < 2^{50}\)
code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445#include <bits/stdc++.h>using namespace std;typedef long ...
莫队
莫队
莫队主要用来快速处理一个数组中多个区间内不同数字的状态
核心思想
分块:把长度为 \(n\) 的数组分为 若干个 长度为\(\sqrt{n}\) 的块
离线:对于所有的查询,按照双关键字排序,同一块内按右端点从小到大,否则按块的先后顺序从左到右
定义两个指针 \(l, r\),代表当前维护的区间是 \([l,r]\),对于排好序的查询,用双指针依次扫描查询的区间,时间复杂度 \(O(n\sqrt{n})\)
复杂度分析
假设查询的数量也是 \(n\) * 对于 \(l\) 指针,假设每个块内的查询,\(l\) 都要从左到右或者从右到左,每次的距离是\(\sqrt{n}\),则一共需要跑 \(n\sqrt{n}\)
* 对于 \(r\) 指针,假设每当查询完一个块,\(r\) 指针都在 \(n\),并且要到当前块的最右边,则一共需要跑 \(n\sqrt{n}-\frac{(1+\sqrt{n})*\sqrt{n}}{2}\)
因此总时间复杂度为 \(O(n\sqrt{n})\)
常数优化
每个块内查询的右边界都是升序排序,导致相邻块过渡的时候,右边界相距过远
因此可以奇数块内 ...
Codeforces Round 974 (Div. 3) 题解
A. Robin Helps
模拟
code:
123456789101112131415161718192021222324252627282930#include <bits/stdc++.h>using namespace std;const int N = 55;int T;int n, k;int a[N];int main(){ cin >> T; while (T--) { cin >> n >> k; for (int i = 0; i < n; i++) cin >> a[i]; int res = 0, sum = 0; for (int i = 0; i < n; i++) { if (a[i] >= k) sum += a[i]; else if (!a[i] && sum) res++, su ...
牛客周赛 Round 61 题解
A. Letter Song ~ 致十年后的我们
处理出来年份,\(+10\) 后输出
code:
1234567891011121314151617181920#include <bits/stdc++.h>using namespace std;string s;int main(){ cin >> s; int x = 0; for (int i = 0; i < 4; i++) x = x * 10 + s[i] - '0'; x += 10; cout << x; for (int i = 4; i < s.size(); i++) cout << s[i]; return 0;}
B. 简单图形问题 - 0123
手动模拟可以发现,边长为整数的等边三角形面积不可能是整数,因此只需要判断 \(s\) 是否是平方数即可
code:
123456789101112131415161718192021222324252627282930#in ...
Codeforces Round 955 (Div. 2, with prizes from NEAR!) 题解
A. Soccer
只有一种情况会导致两队的分持平,就是前后两队比分出现反超
code:
123456789101112131415161718192021222324252627282930313233#include <bits/stdc++.h>#define int long long#define x first#define y second#define endl '\n'using namespace std;typedef pair<int, int> PII;const int N = 200010;int T;int n;int x1, yl, x2, y2;signed main(){ ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> T; while (T--) { cin >> x1 >> yl >> x2 >> y2; ...
Codeforces Round 973 (Div. 2) 题解
A. Zhan's Blender
搅拌机一秒最多能搅拌 \(min(x,c)\) 个水果,因此搅拌的总时间为 \(\lceil\frac{n}{min(x,c)}\rceil\)
code:
1234567891011121314151617181920212223242526272829303132#include <bits/stdc++.h>#define int long long#define x first#define y second#define endl '\n'using namespace std;typedef pair<int, int> PII;const int N = 200010;int T;int n, x, y;signed main(){ ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> T; while (T--) { cin >> n & ...
ST表
ST 表 (Sparse Table,稀疏表)
主要用来解决 \(RMQ\) (区间最大/最小值查询)问题。应用倍增思想,可以实现 \(O(nlogn)\) 预处理、\(O(logn)\) 查询。
预处理 ST 表
倍增法递推:用两个等长的小区间组合成大区间
以区间最大值为例:\(f[i][j]\) 表示以第 \(i\) 个数为起点,长度为 \(2^j\) 的区间最大值
\(f[i][j]=max(f[i][j-1],f[i+2^j-1][j-1])\)
查询
对查询区间 \([l,r]\) 进行分割
设 \(k=log_2(r-l+1)\)
则区间 \([l,r]\) 可以分割成 \([l,l+2^k-1]\) 和 \([r-2^k+1,r]\),用预处理的 \(f\) 数组进行查询即可,中间的重叠部分无需理会
例题
Luogu P3865 【模板】ST 表 && RMQ 问题
题目描述
给定一个长度为 \(N\) 的数列,和 \(M\) 次询问,求出每一次询问的区间内数字的最大值。
输入格式
第一行包含两个整数 \(N,M\),分别表示数列的长度和询问的个数。
第二 ...
Codeforces Round 972 (Div. 2) 题解
A. Simple Palindrome
可以发现,两个相同的字母产生的回文子串与它们之间间隔的字母个数有关,因此考虑把 \(n\) 个字母分配给 \(aeiou\),并且相同的元素相邻
code:
123456789101112131415161718192021222324252627282930313233343536373839#include <bits/stdc++.h>#define int long long#define x first#define y secondusing namespace std;typedef pair<int, int> PII;const int N = 200010;int T;int n;int a[N];signed main(){ cin >> T; while (T--) { cin >> n; string s = "aeiou"; int x = n / 5, ...