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\))
考虑数组纯随机生成的 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;
}
草稿纸上随便推几组数据,可以发现:若区间 \([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;
}
TBD...
TBD...

浙公网安备 33010602011771号