2024/09/22 模拟赛总结

没考,0+0+0+0=0

#A. 集合

今年T1考去年T4是吧

#B. 出租

Sum[l,r]>k(rl+d+1) 是无解,移项得 i=lraxk>kd

用线段树维护最大子段和,然后和 kd 比大小即可。

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

using namespace std;
using LL = long long;

const int kMaxN = 5e5 + 5;

LL ls(LL x) { return x << 1; }
LL rs(LL x) { return x << 1 | 1; }

struct SegmentTree {
  LL c[kMaxN << 2], lm[kMaxN << 2], rm[kMaxN << 2], mx[kMaxN << 2];
  void PushUp(int x) { 
    c[x] = c[ls(x)] + c[rs(x)], mx[x] = max({mx[ls(x)], mx[rs(x)], lm[rs(x)] + rm[ls(x)]});
    lm[x] = max(lm[ls(x)], c[ls(x)] + lm[rs(x)]), rm[x] = max(rm[rs(x)], c[rs(x)] + rm[ls(x)]);
  }
  void Build(int x, int l, int r, LL k) {
    if (l == r) {
      c[x] -= k, lm[x] = rm[x] = mx[x] = c[x];
      return;
    }
    int mid = (l + r) >> 1;
    Build(ls(x), l, mid, k), Build(rs(x), mid + 1, r, k), PushUp(x);
  }
  void Update(int x, int l, int r, int ql, int qr) {
    if (l == r) {
      c[x] += qr, lm[x] = rm[x] = mx[x] = c[x];
      return;
    }
    int mid = (l + r) >> 1;
    mid >= ql ? Update(ls(x), l, mid, ql, qr) : Update(rs(x), mid + 1, r, ql, qr);
    PushUp(x);
  }
  bool Query(LL p) {
    return mx[1] <= p;
  }
};

LL n, m, k, d, l, r;
SegmentTree tr;

void pr(bool pr) {
  cout << (pr ? "YES" : "NO") << '\n';
}

int main() {
	freopen("hire.in", "r", stdin);
	freopen("hire.out", "w", stdout);
  for (cin >> n >> m >> k >> d, tr.Build(1, 1, n - d, k); m; m--) {
    cin >> l >> r, tr.Update(1, 1, n - d, l, r), pr(tr.Query(k * d));
  }
  return 0;
}

#C. 跳棋

跳子可以抽象成 110011,011110,即 110 交换位置。

dpi,j,k,0/1 表示到了第 i 位,有 j11k0si 后接一个 1 能否变成 11

对于每个 dpn,i,j0/1,乘上 Ci+ji

注意需要滚掉一维

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

using namespace std;
using LL = long long;

const int kMaxN = 5e2 + 5;
const LL kP = 1e9 + 7;

LL n, dp[2][kMaxN][kMaxN][2], f[kMaxN], ans;
string s;

LL P(LL x, LL y, LL ret = 1) {
  for (; y; (y & 1) && ((ret *= x) %= kP), (x *= x) %= kP, y >>= 1) {
  }
  return ret;
}
LL C(LL p, LL k) {
  return f[p] * P(f[k] * f[p - k] % kP, kP - 2) % kP;
}

int main() {
  freopen("checkers.in", "r", stdin), freopen("checkers.out", "w", stdout), f[0] = 1;
  for (int i = 1; i < kMaxN; i++) {
    f[i] = f[i - 1] * i % kP;
  }
  cin >> n >> s, s = ' ' + s, dp[0][0][0][0] = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= i; j++) {
      for (int k = 0; k <= i; k++) {
        for (int l = 0; l <= 1; l++) {
          if (dp[0][j][k][l]) {
            (s[i] == '0' || s[i] == '?') && ((dp[1][j][k + 1][0] += dp[0][j][k][l]) %= kP);
            (s[i] == '1' || s[i] == '?') && (l ? (dp[1][j + 1][k][0] += dp[0][j][k][l]) %= kP : (dp[1][j][k][1] += dp[0][j][k][l]) %= kP);
          }
        }
      }
    }
    for (int j = 0; j <= n; j++) {
      for (int k = 0; k <= n; k++) {
        for (int l = 0; l <= 1; l++) {
          dp[0][j][k][l] = dp[1][j][k][l], dp[1][j][k][l] = 0;
        }
      }
    }
  }
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      LL e = (dp[0][i][j][0] + dp[0][i][j][1]) % kP;
      (ans += (e * C(i + j, i))) %= kP;
    }
  }
  cout << ans << '\n';
  return 0;
}

#D. 连通块

dpi,j 为树根为 i,最后一个 dfnj 的最大值。

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

using namespace std;
using LL = long long;

const int kMaxN = 1e5 + 5, kMaxM = 42 + 5;

int n;
LL ans, dp[kMaxN][kMaxM], a[kMaxN], tot, m, f[kMaxN], v[kMaxN], p[kMaxM][kMaxM], l[kMaxM], r[kMaxM];
vector<int> g[kMaxN];

void DFS(int u, LL ret = -1e18) {
  dp[u][f[u]] = a[u];
  for (int v : g[u]) {
    DFS(v);
    for (int i = 0; i <= tot; i++) {
      (!p[i][f[v]]) && (ret = max(ret, dp[u][i]));
    }
    for (int i = 0; i <= tot; i++) {
      dp[u][i] = max(dp[u][i], dp[v][i] + ret);
    }
  }
}

int main() {
  freopen("block.in", "r", stdin);
  freopen("block.out", "w", stdout);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  if (*max_element(a + 1, a + n + 1) <= 0) {
    cout << *max_element(a + 1, a + n + 1) << '\n';
    return 0;
  }
  for (int i = 1, sz, x; i <= n; i++) {
    for (cin >> sz; sz; sz--) {
      cin >> x, g[i].push_back(x);
    }
  }
  for (int i = 1; i <= m; i++) {
    cin >> l[i] >> r[i], v[l[i]] = v[r[i]] = 1;
  }
  for (int i = 1; i <= n; i++) {
    v[i] && (f[i] = ++tot);
  }
  for (int i = 1; i <= m; i++) {
    p[f[l[i]]][f[r[i]]] = p[f[r[i]]][f[l[i]]] = 1;
  }
  fill(dp[0], dp[kMaxN - 1], -1e18), DFS(1), ans = -1e18;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= tot; j++) {
      ans = max(ans, dp[i][j]);
    }
  }
  cout << ans << '\n';
  return 0;
}
posted @   BluemoonQwQ  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
点击右上角即可分享
微信分享提示