AtCoder Beginner Contest 367

1|0A - Shout Everyday

思路:水题一道,模拟即可。

2|0B - Cut .0

思路:直接 cincout 即可,c++输入输出性质。

3|0C - Enumerate Sequences

思路:注意到数据范围很小,因此考虑到搜素所有的序列,然后判断是否合法。

4|0D - Pedometer

思路:观察到是环上问题,先断环为链,观察题目,可以发现,对于 s,它的终点范围在 [s+1,s+n-1]。同时,设 a 为到 s 的步数,设 b 为到 t 的步数,题目的限制条件可以转化为 (b - a) mod k = 0,即 b mod k = a mod k。因此,我们可以用哈希表来维护。

代码:

#include <bits/stdc++.h> #define int long long #define ull unsigned long long #define ios ios::sync_with_stdio(0) #define endl '\n' #define pii pair<int, int> #define debug(x) cout << "x = " << x << endl; #define lowbit(x) (x & (-x)) using namespace std; const int N = 5e5 + 5, P = 13331; int n, a[N], m, ans; map<int, int> cnt; void solve() { int T = 1; // cin>>T; while (T--) { cin >> n >> m; for (int i = 2; i <= n + 1; i++) { cin >> a[i]; } for (int i = n + 2; i <= 2 * n; i++) { a[i] = a[i - n]; } for (int i = 1; i <= 2 * n; i++) { a[i] = (a[i] + a[i - 1]) % m; } for (int i = 1; i <= n; i++) { cnt[a[i]]++; } for (int i = 1; i <= n; i++) { cnt[a[i]]--; ans += cnt[a[i]]; cnt[a[i + n]]++; } cout << ans; } } signed main() { ios; solve(); return 0; }

5|0E - Permute K times

思路:可以观察到,每个点其实对应一个基环树,问题转化为求每个基环树的第k个点。考虑倍增。

代码:

/* * @OJ: * @ID: * @Author: ZhangChao * @Date: 2024-08-22 13:06:50 */ #include <bits/stdc++.h> #define int long long #define ull unsigned long long #define ios ios::sync_with_stdio(0) #define endl '\n' #define pii pair<int, int> #define debug(x) cout << "x = " << x << endl; #define lowbit(x) (x & (-x)) using namespace std; const int N = 5e5 + 5, P = 13331; int n, x[N], a[N], k; int dp[N][63]; int get(int d, int id) { int s = id; for (int i = 62; i >= 0; i--) { if (((int)1 << i) <= d) { d -= ((int)1 << i); s = dp[s][i]; } } return a[s]; } void solve() { int T = 1; // cin>>T; while (T--) { cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> x[i]; } for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { dp[i][0] = x[i]; } for (int i = 1; i < 63; i++) { for (int j = 1; j <= n; j++) { dp[j][i] = dp[dp[j][i - 1]][i - 1]; } } for (int i = 1; i <= n; i++) { cout << get(k, i) << " "; } } } signed main() { ios; solve(); return 0; }

6|0F - Rearrange Query

思路:问题为判断子串 a[l:r]a[l:r]b[L:R]b[L:R] 作为多重集是否相等。一个熟知的判断多重集相等的办法是哈希。即将多重集映射为一个数,以数的相等多重集的相等,这个数称作哈希值。为了确保正确性,需要在映射过程中引入随机性,即随机哈希并通过分析证明错误概率极小。当随机数值域为 [0,m) ,可以证明哈希碰撞的概率不超过 gcd(n,m)/m。代码实现上,可以取 m = 2^64,使用 unsigned long long 进行计算,并使用 C++ 中的伪随机数生成器 std::mt19937_64 来生成随机数。

代码:

/* * @OJ: * @ID: * @Author: ZhangChao * @Date: 2024-08-22 13:56:50 */ #include <bits/stdc++.h> #define int long long #define ull unsigned long long #define ios ios::sync_with_stdio(0) #define endl '\n' #define pii pair<int, int> #define debug(x) cout << "x = " << x << endl; #define lowbit(x) (x & (-x)) using namespace std; const int N = 5e5 + 5, P = 13331; ull a[N], b[N], n, q, g[N]; void solve() { int T = 1; // cin>>T; while (T--) { mt19937_64 rng(time(0)); cin >> n >> q; for (int i = 1; i <= n; i ++) { g[i] = rng(); cin >> a[i]; } for (int i = 1; i <= n; i ++) { cin >> b[i]; } for (int i = 1; i <= n; i ++) { a[i] = a[i - 1] + g[a[i]]; b[i] = b[i - 1] + g[b[i]]; } for (int i = 1, l, r, L, R; i <= q; i ++) { cin >> l >> r >> L >> R; if(a[r]-a[l-1] == b[R] - b[L-1]) cout << "Yes" << endl; else cout << "No" << endl; } } } signed main() { ios; solve(); return 0; }

__EOF__

本文作者小张
本文链接https://www.cnblogs.com/zc-study-xcu/p/18373634.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   xcuzc  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
点击右上角即可分享
微信分享提示