2023/10/15 模拟赛总结

没考,\(0+0+0+0=0\)

T1 - tv

单调栈求最小值为当前有趣程度最大的区间左右端点,ST表求区间最大值。

// J2023 | BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using ULL = unsigned long long;

const int kMaxN = 2e6 + 5, kMaxLog = 21;

int n, top, st[kMaxN][kMaxLog + 1], s[kMaxN], l[kMaxN], r[kMaxN];
ULL ans;

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (cin >> st[i][0]; top && st[s[top]][0] >= st[i][0]; top--){
    }
    l[i] = s[top], s[++top] = i;
  }
  top = 0;
  for (int i = n; i; i--) {
    for (; top && st[s[top]][0] >= st[i][0]; top--){
    }
    r[i] = (s[top] ? s[top] : n + 1), s[++top] = i;
  }
  for (int j = 1; j <= kMaxLog; j++) {
    for (int i = 0; i <= n - (1 << j) + 1; i++) {
      st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
    }
  }
  for (int i = 1, q, t; i <= n; i++) {
    if (st[i][0] > 0) {
      t = log2(r[i] - l[i] - 1);
      q = max(st[l[i] + 1][t], st[r[i] - (1 << t)][t]);
      ans = max((((ULL)r[i] - (ULL)l[i] - 1ull) * (ULL)st[i][0]) * (ULL)q, ans);
    }
  }
  cout << ans << '\n';
  return 0;
}

T2 - card

不会,好像要权值线段树。

T3 - mo

ez,运用同余即可。

// J2023 | BLuemoon_
#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 1e5 + 5;

int n, d, s[kMaxN], ans, c;

int main() {
  cin >> n >> d;
  for (int i = 1, x; i <= n; i++) {
    cin >> x;
    s[i % d] += x;
  }
  for (int i = 0; i < d; i++) {
    ans += s[i], c = max(c, s[i]);
  }
  cout << ans - c << '\n';
  return 0;
}

T4 - set

考虑集合为 \(\{[1,n] \cap \mathbb{N}\}\),所以子集和的范围是 \([1,\frac{n \times(n + 1)}{2}]\),所以用 \(\text{dp}\) 求出每一个和出现的次数 \(\text{dp}_i\),答案就是 \(\prod i^{\text{dp}_i}\)。但是这里不能取模,于是我们充分发扬人类智慧,所以我们使用费马小定理:当 \(\gcd(a,p) = 1\)\(p\) 为质数时,\(a^{p-1} \equiv 1 \ \ (\!\bmod p)\)。于是我们在更新 \(\text{dp}\) 数组时取模 \(998244352\),求答案时再取模 \(998244353\) 即可。

// J2023 | BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int kMaxN = 2e2 + 5;
const LL P = 998244353;

LL n, dp[kMaxN * kMaxN] = {1}, ans = 1;

LL C(LL a, LL b) {
  LL ans = 1;
  for (; b; (b & 1) && ((ans *= a) %= P), (a *= a) %= P, b >>= 1) {
  }
  return ans % P;
}
LL Q(LL x) {
  return x * (x + 1) >> 1;
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = Q(n); j - i >= 0; j--) {
      (dp[j] += dp[j - i]) %= (P - 1);
    }
  }
  for (LL i = 1; i <= Q(n); (ans *= C(i, dp[i])) %= P, i++) {
  }
  cout << ans << '\n';
  return 0;
}
posted @ 2023-10-15 17:37  BluemoonQwQ  阅读(13)  评论(0编辑  收藏  举报