P9870 [NOIP2023] 双序列拓展 题解
P9870 [NOIP2023] 双序列拓展 题解
NOIP2023 T3,特殊性质题。
什么是特殊性质题?就是题目给出了你极其神秘的性质,从而引导你想出正解。
本篇题解将从部分分的角度,一步步讲述部分分与正解的关系。这样看的话,本题会变得十分简单。
简化题意其实就是要求满足最终序列里的
看上去
那么对于
代码:
int DP() {
if (x[1] == y[1]) return 0;
int fg = 0;
if (y[1] > x[1]) fg = 1;
memset(dp, 0, sizeof dp);
dp[1][1] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (dp[i][j]) {
if (fg == 0 && x[i + 1] > y[j]) dp[i + 1][j] = 1;
if (fg == 1 && y[j] > x[i + 1]) dp[i + 1][j] = 1;
if (fg == 0 && x[i] > y[j + 1]) dp[i][j + 1] = 1;
if (fg == 1 && y[j + 1] > x[i]) dp[i][j + 1] = 1;
}
return dp[n][m];
}
特殊性质
dp 的状态是难以优化的,考虑特殊性质是什么意思。
simple 的想法是枚举
但这样显然没有正确性,原因是当前
如何解决这个问题?要让更多的
代码:
int chk() {
for (int i = 1; i <= n; i++)
mx[i] = max(mx[i - 1], y[i]);
int j = 0, mn = 1e9;
for (int i = 1; i <= n; i++) {
if (x[i] < mn) {
while (j < m && x[i] < y[j + 1])
++j;
}
else if(x[i] >= mx[j]) return 0;
mn = min(mn, x[i]);
}
return j == m;
}
正解
特殊性质的提示还 TM 不够明显吗??
将
完整代码:
#include <bits/stdc++.h>
#define N 500005
#define int long long
using namespace std;
int c, n, m, q;
int x[N], y[N], xx[N], yy[N];
int mx[N];
int nx[N], ny[N];
int chk(int p, int q) {
if (nx[1] >= ny[1]) return 0;
mx[0] = -1e9;
for (int i = 1; i <= q; i++)
mx[i] = max(mx[i - 1], ny[i]);
int j = 0, mn = 1e9;
for (int i = 1; i <= p; i++) {
if (nx[i] < mn) {
while (j < q && nx[i] < ny[j + 1])
++j;
}
else if(nx[i] >= mx[j]) return 0;
mn = min(mn, nx[i]);
}
return j == q;
}
int kudo() {
if (x[1] == y[1]) return 0;
if (x[1] > y[1]) {
swap(x, y);
swap(n, m);
}
int mn = 1e9, p = 0;
for (int i = 1; i <= n; i++)
mn = min(mn, x[i]);
for (int i = 1; i <= n; i++)
if (mn == x[i]) {
p = i;
break;
}
int mx = -1e9, q = 0;
for (int i = 1; i <= m; i++)
mx = max(mx, y[i]);
for (int i = 1; i <= m; i++)
if (mx == y[i]) {
q = i;
break;
}
int cp = 0, cq = 0;
for (int i = 1; i <= p; i++)
nx[++cp] = x[i];
for (int i = 1; i <= q; i++)
ny[++cq] = y[i];
int ans = chk(cp, cq);
cp = 0, cq = 0;
for (int i = n; i >= p; i--)
nx[++cp] = x[i];
for (int i = m; i >= q; i--)
ny[++cq] = y[i];
ans &= chk(cp, cq);
return ans;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> c >> n >> m >> q;
for (int i = 1; i <= n; i++)
cin >> x[i], xx[i] = x[i];
for (int i = 1; i <= m; i++)
cin >> y[i], yy[i] = y[i];
int nn = n, mm = m;
cout << kudo();
for (int w = 1; w <= q; w++) {
int nx, ny;
cin >> nx >> ny;
while (nx--) {
int p, t;
cin >> p >> t;
x[p] = t;
}
while (ny--) {
int p, t;
cin >> p >> t;
y[p] = t;
}
cout << kudo();
n = nn, m = mm;
for (int i = 1; i <= n; i++)
x[i] = xx[i];
for (int i = 1; i <= m; i++)
y[i] = yy[i];
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!