2021暑假模拟赛2
A[HDU6954(1500)]
可以通过贪心的思想发现每个数连向自己的因数最优,那么只有质数是特殊的,所以筛出质数单独统计即可。
#include <bits/stdc++.h> using namespace std; vector<bool> GetPrime(int n) { vector<bool> mark(n + 1); vector<int> Prime; for (int i = 2; i <= n; ++i) { if (!mark[i]) { Prime.emplace_back(i); } for (int j = 0; j < Prime.size() && i * Prime[j] <= n; ++j) { mark[i * Prime[j]] = true; if (i % Prime[j] == 0) { break; } } } return mark; } int main() { int T; cin >> T; vector<bool> mark = GetPrime(10000000); while (T --> 0) { int N; cin >> N; long long Ans = 0; for (int i = 3; i <= N; ++i) { if (!mark[i]) { Ans += i * 2; } else { Ans += i; } } cout << Ans << '\n'; } }
B[ABC179D(1251)]
考虑$dp$,$dp[i]$表示走到$i$的方案数,那么暴力转移枚举所有合法的$d$即可。但是这样会超时,于是用前缀和优化$dp$即可。
#include <bits/stdc++.h> using namespace std; const int P = 998244353; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; vector<int> l(k); vector<int> r(k); for(int i = 0; i < k; ++i) { cin >> l[i] >> r[i]; } vector<long long> dp(n + 1); vector<long long> pre(n + 1); dp[1] = 1; for(int i = 1; i <= n; ++i) { for(int j = 0; j < k; ++j) { dp[i] += pre[max(0, i - l[j])] - pre[max(0, i - r[j] - 1)]; dp[i] = (dp[i] % P + P) % P; } pre[i] = (pre[i - 1] + dp[i]) % P; } cout << dp[n] << '\n'; return 0; }
C[ABC164D(1232)]
考虑十进制的形式,可以发现类似字符串哈希,于是相当于求多少个子串的哈希值为2019倍数,于是利用前缀和优化计数即可。
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s; cin >> s; reverse(s.begin(), s.end()); int sum = 0; map<int, int> mp; ++mp[0]; long long ans = 0; long long pw = 1; for(char c : s) { sum = (sum + (c - '0') * pw) % 2019; pw = pw * 10 % 2019; ans += mp[sum]; ++mp[sum]; } cout << ans << '\n'; return 0; }
D[CF1444B(1900)]
可以发现无论怎样分配,这个式子的和都是前$N$大的数-后$N$大的数,于是利用组合数统计即可。
#include <bits/stdc++.h> using namespace std; const int P = 998244353; long long power(long long x, long long t) { long long ret = 1; for (; t; t >>= 1, x = x * x % P) { if (t & 1) { ret = ret * x % P; } } return ret; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<long long> a(n + n); for (int i = 0; i < n + n; ++i) { cin >> a[i]; } sort(a.begin(), a.end()); long long sum = 0; for (int i = 0; i < n; ++i) { sum = (sum + P - a[i]) % P; } for (int i = n; i < n + n; ++i) { sum = (sum + a[i]) % P; } for (int i = 1; i <= n + n; ++i) { sum = sum * i % P; } for (int i = 1; i <= n; ++i) { long long inv = power(i, P - 2); sum = sum * inv % P; sum = sum * inv % P; } cout << sum << '\n'; return 0; }