小蛐蛐 NOIP Round 1 总结

分数:\(100 + 15 + 0 + 0 = 115\)

为什么这“NOIP 模拟赛”里三道题都用到了 9 级知识点。真是无敌了。

不过由于不少同学的摆烂态度,我竟然意外捞到了 ZYZ rank 1,总 rank 2,有点意思。

T1

我用了一个和题解略有不同的思路。

题面描述很玄乎,实际上就是从原树中选出来一个连通块。

\(f(i, 0/1)\) 表示目前考虑到节点 \(i\),且 \(i\) 是/否作为连通块的根时,所能获得的最大分数。初始时 \(f(i, 1) = score(0), f(i, 0) = score(1)\),因为当一个节点不是根时,它上方永远有一条边与之相连,也就是说度数至少为 \(1\)

我们从下往上进行转移,就像一般的树形 DP 一样。对于每一个非叶节点 \(u\),我们对其子节点 \(v\) 按照 \(f(v, 0)\) 进行排序,并计算其前缀和 \(sum\)。如果我们选择 \(i\) 个节点,那么当 \(u\) 作为根时,其度数为 \(i\);当 \(u\) 不作为根时,其度数为 \(i + 1\),因为其上面还有一条边。因此,我们可以得到状态转移方程:

\[f(u, 0) = \max(f(u, 0), \max_{i=1}(score(i + 1) + sum(i))) \\ f(u, 1) = \max(f(u, 1), \max_{i=1}(score(i) + sum(i))) \]

最后我们统计答案时,取 \(\max_{u=1}^{n}(f(u, 1))\) 即可。

#include <bits/stdc++.h>
#define int long long
const int N = 2e5+10;
std::vector<int> g[N];
int n, score[N], dp[N][2];

void dfs(int u, int pre) {
  dp[u][0] = score[1]; dp[u][1] = score[0];
  std::vector<int> chiDP;
  for (auto &v : g[u]) {
    if (v == pre) continue;
    dfs(v, u);
    chiDP.push_back(dp[v][0]);
  }
  std::sort(chiDP.begin(), chiDP.end(), [](int a, int b) {
    return a > b;
  });
  for (int i = 1; i < chiDP.size(); i++) {
    chiDP[i] += chiDP[i-1];
  }
  for (int i = 0; i < chiDP.size(); i++) {
    dp[u][0] = std::max(dp[u][0], score[i+2] + chiDP[i]);       
    dp[u][1] = std::max(dp[u][1], score[i+1] + chiDP[i]);
  }
}

signed main() {
  freopen("tree.in", "r", stdin);
  freopen("tree.out", "w", stdout);
  std::ios::sync_with_stdio(false); std::cin.tie(0);
  std::cin >> n;
  for (int i = 0; i <= n - 1; i++) {
    std::cin >> score[i];
  }
  score[n] = score[n-1];
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    std::cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1, 0);
  int ans = -1e18;
  for (int i = 1; i <= n; i++) {
    ans = std::max(ans, dp[i][1]);
  }
  std::cout << ans << '\n';
  return 0;
}

T3

感觉我再怎么说也没有 XQQ 自己说的好,直接搬过来吧。(我怎么这么懒。)

#include <bits/stdc++.h>
#define int long long
const int N = 1e6+10, MOD = 1e9+7;
int T;
int border[N], nxt0[N], nxt1[N], f[N], sumF[N];

inline std::string decode(std::string s, int len) {
  std::string res;
  for (auto const &ch : s) {
    int num;
    if (ch >= 'a' && ch <= 'z') num = ch - 'a';
    else num = ch - 'A' + 26;
    for (int i = 4; i >= 0; i--) {
      if (num & (1 << i)) res.push_back(1);
      else res.push_back(0);
    }
  } 
  if (res.size() > len) return res.substr(0, len);
  else return res;
}


signed main() {
  freopen("coin.in", "r", stdin);
  freopen("coin.out", "w", stdout);
  std::ios::sync_with_stdio(false); std::cin.tie(0);
  std::cin >> T;
  while (T--) {
    memset(border, 0, sizeof border);
    memset(nxt0, 0, sizeof nxt0);
    memset(nxt1, 0, sizeof nxt1);
    memset(f, 0, sizeof f);
    memset(sumF, 0, sizeof sumF);
    int n, m;
    std::string s1_, s2_;
    std::cin >> n >> s1_ >> m >> s2_;
    std::string s1 = decode(s1_, n), s2 = decode(s2_, m);
    if (n == 0) {std::cout << "0\n"; continue;}

    border[0] = 0;
    for (int i = 1; i < n; i++) {
      int j = border[i-1];
      while (j > 0 && s1[i] != s1[j]) j = border[j-1];
      if (s1[i] == s1[j]) j++;
      border[i] = j;
    }

    nxt0[0] = (s1[0] == 0), nxt1[0] = (s1[0] == 1);
    for (int i = 1; i < n; i++) {
      nxt0[i] = (s1[i] == 0) ? i + 1 : nxt0[border[i - 1]];
      nxt1[i] = (s1[i] == 1) ? i + 1 : nxt1[border[i - 1]];
    }
    int curr = 0; bool done = false;
    for (auto const &ch : s2) {
      if (ch == 0) curr = nxt0[curr];
      else curr = nxt1[curr];
      if (curr == n) {done = true; break;}
    }
    if (done) {std::cout << "0\n"; continue;}

    for (int i = 0; i < n; i++) {
      int j;
      if (s1[i] == 0) j = nxt1[i];
      else j = nxt0[i];
      int s = 0;
      if (i > 0) s = sumF[i-1];
      if (j > 0) s = (s - sumF[j-1] + MOD) % MOD;
      f[i] = (2 + s) % MOD;
      if (i == 0) sumF[i] = f[i];
      else sumF[i] = (sumF[i-1] + f[i]) % MOD;
    }

    if (curr == 0) std::cout << sumF[n-1] << '\n';
    else std::cout << (sumF[n-1] - sumF[curr-1] + MOD) % MOD << '\n';
  }
  return 0;
}
posted @ 2025-11-21 17:18  JZ8  阅读(4)  评论(0)    收藏  举报