补题链接:Here

A. Array and Peaks

题意:给定 数组大小 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图1 和 峰值点 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图2 请问是否存在这样的排序,不存在则输出-1

先序从 i = 2 开始填,依次 i += 2 ,如果这样还有不够即 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图3 则肯定不存在这种排序。

接下来就是填空位了

AC 代码:

  1. void solve() {
  2. int n, k;
  3. cin >> n >> k;
  4. vector<int> a(n + 1);
  5. int nn = n;
  6. for (int i = 2; i <= n; i += 2) {
  7. if (k == 0) break;
  8. a[i] = nn--, k--;
  9. }
  10. if (k) {
  11. cout << -1 << "\n";
  12. return;
  13. }
  14. int cur = 1;
  15. for (int i = 1; i <= n; ++i)
  16. if (!a[i]) a[i] = cur++;
  17. for (int i = 1; i <= n; ++i) cout << a[i] << " ";
  18. cout << "\n";
  19. }

B. AND Sequences

这道题,仍是看了题解都没怎么理解是这样子做的

  1. using ll = long long;
  2. const ll mod = 1e9 + 7;
  3. void solve() {
  4. int n;
  5. cin >> n;
  6. vector<int> a(n);
  7. for (int &x : a) cin >> x;
  8. int h = 0;
  9. for (int i = 0; i < 30; ++i) {
  10. h |= 1 << i;
  11. for (int x : a)
  12. if (not((x >> i) & 1)) h &= ~(1 << i);
  13. }
  14. int c = count(a.begin(), a.end(), h);
  15. ll ans = (ll)c * (c - 1) % mod;
  16. for (int i = 1; i <= n - 2; ++i) ans = ans * i % mod;
  17. cout << ans << '\n';
  18. }

C. Add One

题意很容易懂:现给一个大数 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图4Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图5 次操作机会,每次操作都要使 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图6 的每个位数 + 1,满十进一。如:Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图7

思路:

由于 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图8 的范围在 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图9 就别想着暴力了,尝试 DP + 预处理

预处理部分: $DP_{(i,j)}\ $ 代表第 i 次操作时位数值时 j 的变化值

Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图10%20%3D%20j%20%3C%209%5C%20%3F%5C%20dp(i%20-%201%2Cj%20%2B%201)%20%3A%20(dp(i-1%2C0)%20%2B%20dp(i%20-%201%2C1)%5C%20%5C%25%5C%20mod)%0A#card=math&code=init%3Adp%5B0%5D%5Bi%5D%20%3D%201%5C%5C%0Adp%28i%2Cj%29%20%3D%20j%20%3C%209%5C%20%3F%5C%20dp%28i%20-%201%2Cj%20%2B%201%29%20%3A%20%28dp%28i-1%2C0%29%20%2B%20dp%28i%20-%201%2C1%29%5C%20%5C%25%5C%20mod%29%0A)

  1. int M = 2e5 + 10;
  2. vector<vector<int>> dp(M + 1, vector<int>(10));
  3. void init() {
  4. for (int i = 0; i < 10; ++i) dp[0][i] = 1;
  5. for (int i = 1; i <= M; ++i)
  6. for (int j = 0; j < 10; ++j) {
  7. if (j < 9) dp[i][j] = dp[i - 1][j + 1];
  8. else
  9. dp[i][j] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
  10. }
  11. }

所以根据 DP 数组,可以快速得到输入值 n,m的情况下最后的位数

  1. void solve() {
  2. string s;
  3. int m;
  4. cin >> s >> m;
  5. ll ans = 0;
  6. for (char c : s) ans = (ans + dp[m][c - '0']) % mod;
  7. cout << ans << "\n";
  8. }

赛后看了下官方题解,发现可以把二维DP压缩为一位DP

Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图11 定义为对数字 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图12 进行 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图13 次运算以后的字符串长度

  • Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图14 in Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图15

  • Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图16 if Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图17
    即对数字 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图18 进行 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图19 次运算后最终数字为 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图20

  • 对于其他情况:Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图21
    长度是 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图22 次运算和 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图23 次运算的和

这里同样先预处理

最后的答案为 Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图24(s%5Bi%5D%20-%20’0’)%20%3C%2010)%3F1%3Adp%7Bm-10%2B(int)(s%5Bi%5D%20-%20’0’)%7D)#card=math&code=ans%20%3D%20%5Csum%7Bi%20%3D%201%7D%5E%7B%7Cs%7C%7D%28%28m%20%2B%20%28int%29%28s%5Bi%5D%20-%20%270%27%29%20%3C%2010%29%3F1%3Adp_%7Bm-10%2B%28int%29%28s%5Bi%5D%20-%20%270%27%29%7D%29)

  • 时间复杂度为:Codeforces Round #714 (Div. 2) Divide by Zero 2021 个人补题记录 - 图25#card=math&code=%5Cmathcal%7BO%7D%28m%2Bt%C2%B7%7Cs%7C%29)
  1. #define int long long
  2. const int max_n = 200005, mod = 1000000007;
  3. int dp[max_n];
  4. signed main() {
  5. for (int i = 0; i < 9; i++) dp[i] = 2;
  6. dp[9] = 3;
  7. for (int i = 10; i < max_n; i++) {
  8. dp[i] = (dp[i - 9] + dp[i - 10]) % mod;
  9. }
  10. ios_base::sync_with_stdio(false), cin.tie(NULL);
  11. int t;
  12. cin >> t;
  13. while (t--) {
  14. int n, m;
  15. cin >> n >> m;
  16. int ans = 0;
  17. while (n > 0) {
  18. int x = n % 10;
  19. ans += ((m + x < 10) ? 1 : dp[m + x 10]);
  20. ans %= mod;
  21. n /= 10;
  22. }
  23. cout << ans << "\n";
  24. }
  25. return 0;
  26. }