牛客小白月赛101

1|0A - tb的区间问题


枚举区间,然后用前缀和求解

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using vi = vector<int>; using pii = pair<int,int>; i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int n, k; cin >> n >> k; vi a(n + 1); for(int i = 1; i <= n; i ++) cin >> a[i], a[i] += a[i-1]; int res = 0; for(int l = 1, r = n - k; r <= n; l ++, r ++) res = max(res, a[r] - a[l - 1]); cout << res; return 0; }

2|0B -tb的字符串问题


栈模拟一下

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using vi = vector<int>; using pii = pair<int,int>; i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; string s; cin >> s; string t; for(auto c : s){ if(not t.empty() and ((t.back() == 'f' and c == 'c') or (t.back() == 't' and c == 'b'))) t.pop_back(); else t += c; } cout << t.size(); return 0; }

3|0C - tb的路径问题


找规律,发现对于对角线上的每个数字两步之内必有2,但是对于奇数来说,两步之内的2n×n 的外面,因此只能走到前一个偶数上。

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using vi = vector<int>; using pii = pair<int,int>; i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; cout << min(2 * n - 2 , 4 + 2 * (n % 2)); return 0; }

4|0D - tb的平方问题


发现询问的范围并不大,所以我们可以离线计算。

可以枚举出所有的完全平方数,然后利用枚举+二分找到所有的区间,并用差分实现区间修改。

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; #define int i64 using vi = vector<int>; using pii = pair<int,int>; i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int n , q; cin >> n >> q; vi a(n + 1); for(int i = 1; i <= n; i ++) cin >> a[i], a[i] += a[i - 1]; int sum = a[n]; vi p2; for(int i = 1; i * i <= sum; i ++) p2.push_back(i * i); vi res(n + 2); for(const int &v : p2){ for(int l = 1, r, x ; l <= n; l ++){ x = a[l - 1] + v; if(x > sum) break; r = ranges::lower_bound(a, x) - a.begin(); if(a[r] - a[l - 1] == v) res[l] ++, res[r + 1] --; } } for(int i = 1; i <= n ; i ++) res[i] += res[i - 1]; for(int x ; q ; q -- ){ cin >> x; cout << res[x] << "\n"; } return 0; }

5|0E - tb的数数问题


用一个类似埃筛的做法,求出每个数的约数个数,然后再已有的约数,然后比较一下就好了。

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; #define int i64 using vi = vector<int>; using pii = pair<int,int>; const int N = 1e6; bitset<N + 1> vis; i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; for(int i = 1, x; i <= n; i ++) cin >> x, vis[x] = true; vi a(N + 1); for(int i = 1; i <= N; i ++) for(int j = i; j <= N; j += i) a[j] ++; vi b(N + 1); for(int i = 1; i <= N; i ++ ){ if(vis[i] == false) continue; for(int j = i; j <= N; j += i) b[j] ++; } int res = 0; for(int i = 1; i <= N; i++) res += a[i] == b[i]; cout << res; return 0; }

6|0F - tb的排列问题


pos[x]统计ai中非1的数出现的位置。用pre[x]维护出a前缀中1个数。

我们从前往后考虑每一个bi,对于这个数来说,能够和他交换的范围是[i,i+w]

如果bi存在于a中,且在这个范围[1,i+w]内就可以交换过来,答案乘1,否则答案乘0。考虑为什么[1,i1]也可以,因为我们从前往后枚举,所以前缀是一定匹配的,因为如果出现在前面,一定会在之前的某次交换到后面。

如果bi不存在于a中,则需要消耗[1,i+w]内一个1,同时考虑到之前可能已经消耗了一些1所以我们要计算出还剩下了多少1,答案乘以剩下1的个数即可。

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; #define int i64 using vi = vector<int>; using pii = pair<int,int>; const int N = 1e6; bitset<N + 1> vis; const int mod = 998244353; struct mint { int x; mint(int x = 0) : x(x) {} mint &operator=(int o) { return x = o, *this; } mint &operator+=(mint o) { return (x += o.x) >= mod && (x -= mod), *this; } mint &operator-=(mint o) { return (x -= o.x) < 0 && (x += mod), *this; } mint &operator*=(mint o) { return x = (i64) x * o.x % mod, *this; } mint &operator^=(int b) { mint w = *this; mint ret(1); for (; b; b >>= 1, w *= w) if (b & 1) ret *= w; return x = ret.x, *this; } mint &operator/=(mint o) { return *this *= (o ^= (mod - 2)); } friend mint operator+(mint a, mint b) { return a += b; } friend mint operator-(mint a, mint b) { return a -= b; } friend mint operator*(mint a, mint b) { return a *= b; } friend mint operator/(mint a, mint b) { return a /= b; } friend mint operator^(mint a, int b) { return a ^= b; } int val() { x = (x % mod + mod) % mod; return x; } }; void solve() { int n, w; cin >> n >> w; vi a(n + 1); for(int i = 1; i <= n; i ++) cin >> a[i]; vi b(n + 1); for(int i = 1; i <= n; i ++) cin >> b[i]; vi pos(n + 1, -1); for(int i = 1; i <= n; i ++) if(a[i] != - 1) pos[a[i]] = i; vi pre(n + 1); for(int i = 1; i <= n; i ++) pre[i] = pre[i - 1] + (a[i] == -1); mint res(1); for(int i = 1, used = 0; i <= n ;i ++){ if(pos[b[i]] != -1) { res *= pos[b[i]] <= min(i + w, n); } else { res *= pre[min(i + w, n)] - used; used ++; } } cout << res.val() << "\n"; return; } i32 main(){ ios::sync_with_stdio(false), cin.tie(nullptr); int T; cin >> T; while(T --) solve(); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/18427017.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示