2025/8/7 模拟赛总结

\(100+100+5+10=215\),这分数能拿 rk20?

赛时记录:

\(2:22:33\) 写完 A 100pts(\(100\)

\(1:56:21\) 写完 B 100pts(\(200\)

\(1:02:13\) 写完 C 5pts(\(205\)

\(0:52:18\) 写完 D 10pts(\(215\)

#A. 最长上升子序列

考虑数组纯随机生成的 LIS 长度大约为 \(\sqrt{n}\),所以可以每次暴力删点,如果删到了 LIS 中的点则暴力重构,否则直接删去即可

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

using namespace std;
using LL = long long;

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

int T = 1, n, a[kMaxN], p[kMaxN], fr[kMaxN], vis[kMaxN], pos[kMaxN], d[kMaxN], w[kMaxN], cur, cnt, ans[kMaxN];

void pr(bool pr) { cout << (pr ? "Yes" : "No") << '\n'; }
int Solve(int ret = 1) {
  fill(fr, fr + n + 2, 0), fill(vis, vis + n + 2, 0), fill(pos, pos + n + 2, 0), fill(d, d + n + 2, 0);
  for (int i = 1; i <= n; i++) {
    if (!w[i]) {
      int dx = lower_bound(d + 1, d + ret, a[i]) - d;
      d[dx] = a[i], ret += (ret == dx), pos[dx] = i, fr[i] = pos[dx - 1];
    }
  }
  for (int i = pos[--ret]; i; i = fr[i]) {
    vis[i] = 1;
  }
  return ret;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  for (; T; T--) {
    cin >> n, cur = n + 1;
    for (int i = 1; i <= n; i++) {
      cin >> a[i];
    }
    for (int i = 1; i <= n; i++) {
      cin >> p[i];
    }
    ans[--cur] = (cnt = Solve());
    for (int i = n; i > 1; i--) {
      w[p[i]] = 1, vis[p[i]] && (cnt = Solve()), ans[--cur] = cnt;
    }
    for (int i = 1; i <= n; i++) {
      cout << ans[i] << " \n"[i == n];
    }
  }
  return 0;
}

#B. 消除序列

草稿纸上随便推几组数据,可以发现:若区间 \([l,r]\) 满足条件,那么 \(\sum\limits_{r-2i\ge l}a_{r-2i}=\sum\limits_{r-2i-1\ge l}a_{r-2i-1}\),且 \(\forall k\in[l,r],\sum\limits_{m-2i\ge l}a_{m-2i}-\sum\limits_{m-2i-1\ge l}a_{m-2i-1}\ge 0\)。于是可以从小到大枚举 \(r\),开 map 动态求出每次修改的增量,偶数位取反即可

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

using namespace std;
using LL = long long;
using Pll = pair<LL, LL>;

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

LL T = 1, n, a[kMaxN], ans;
map<LL, LL> mp;

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

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  for (cin >> T; T; T--, ans = 0, mp.clear()) {
    cin >> n;
    for (int i = 1; i <= n; i++) {
      cin >> a[i];
    }
    for (int i = 1, typ = 1, del = 0; i <= n; i++, typ = -typ) {
      for (del = a[i] - del, mp[typ * (del - a[i])]++; !mp.empty();) {
        if (typ == 1) {
          if ((*--mp.end()).first > del) {
            mp.erase(--mp.end());
          } else {
            break;
          }
        } else {
          if ((*mp.begin()).first < -del) {
            mp.erase(mp.begin());
          } else {
            break;
          }
        }
      }
      ans += mp[typ * del];
    }
    cout << ans << '\n';
  }
  return 0;
}

#C. 本质不同01串

TBD...

#D. 树上价值

TBD...

posted @ 2025-08-07 17:00  BluemoonQwQ  阅读(24)  评论(0)    收藏  举报