P9870 [NOIP2023] 双序列拓展 题解

news/2024/11/15 20:17:15/文章来源:https://www.cnblogs.com/Rock-N-Roll/p/18548583

P9870 [NOIP2023] 双序列拓展 题解

NOIP2023 T3,特殊性质题。

什么是特殊性质题?就是题目给出了你极其神秘的性质,从而引导你想出正解。

本篇题解将从部分分的角度,一步步讲述部分分与正解的关系。这样看的话,本题会变得十分简单。

\(\text{Task } 1∼7, O(Tnm)\)

简化题意其实就是要求满足最终序列里的 \((f_i-g_i)\) 同号。那么我们只考虑 \(f_i<g_i\) 的情形,另一种是等价的。

看上去 \(l_0\) 很大,但其实只需要计算出 \(X,Y\)\(L\) 序列一一匹配即可。记匹配序列分别为 \(x,y\)

那么对于 \(O(nm)\) 的 dp,套路地设 \(dp_{i,j}\) 表示 \(x\) 匹配到 \(i\)\(y\) 匹配到 \(j\) 的合法性。从 \((i,j)\) 转移到 \((i,j+1)\)\((i+1,j)\) 是容易的。

代码:

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];
}

\(\text{Task } 8∼14, O(T(n+m))\) 特殊性质

dp 的状态是难以优化的,考虑特殊性质是什么意思。

\(x\) 的最小值在序列的最后端,说明这个做法大概和维护一些最小值相关联。又因为这是一个线性的复杂度,使我们想到贪心处理。这样的通常套路是枚举一个变量,同时双指针统计第二个变量去做。

simple 的想法是枚举 \(1\sim m\)\(y\),对于每一个 \(y\) 拓展 \(x\),直到不能拓展为止。并检查合法性。

但这样显然没有正确性,原因是当前 \(y\) “占了过多” 的 \(x\),导致没有足够的合法 \(x\) 和之后的 \(y\) 匹配。

如何解决这个问题?要让更多的 \(y\) 得到匹配,就是不让当前的 \(y\) 去挤占可以去做贡献的更小的 \(x\),也就是 让每个最小的 \(x\) 去拓展更多的 \(y\) 我们转而枚举 \(x\),对于每个 前缀最小值 \(x_i\),我们可以让它尽情放飞地去匹配尽量多的 \(y\),假设匹配到了 \(y_i\),下一个前缀最小值是 \(x_j\),那么 \([x_i,x_{j-1}]\) 直接匹配 \([y_1,y_i]\) 中的最大值 \(y_{\max}\) 是最优的,至于 \(y_{\max}\) 之后的部分,由于是 \(x_i\) 拓展到的,还有 \(x_j\) 等着匹配这些个拓展出的部分,且让 \(x_j\) 去拓展新的序列也一定更优。这样一来事实上形成了一些个区间。由于 \(y\) 的最大值同样在序列末尾,并不存在 \(x\) 到终点之后没有 \(y\) 与之匹配的情形。那么对于不是前缀最小值的 \(x\),检查它和 \(y_{\max}\) 的大小关系即可。这样做正确的核心是在恰当的时机让当前匹配的 \(y\) "放手",避免 "侵占资源",让那个 \(x\) 来拓展更多的 \(y\)

代码:

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;
}

\(\text{Task } 15\sim 20, O(T(n+m))\) 正解

特殊性质的提示还 TM 不够明显吗??

\(x,y\) 序列分别按照最大,最小值分成两段处理即可。

完整代码:

#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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834219.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文件共享服务之实时备份(inotify+rsync)

任务需求 1.对NFS服务器上的静态资源实时备份(inotify+rsync) 主机列表 # 外网地址 内网地址 主机名 192.168.122.207 172.16.1.207 web-test-209 192.168.122.231 172.16.1.231 nfs-test-231 192.168.122.241 172.16.1.241 rsync-test-241架…

专题四:信息安全

信息系统安全属性 机密性:确保信息不暴露给未授权的实体或进程。 完整性:只有得到允许的人才能修改数据,并且能够判断出数据是否已被篡改。 可用性:得到授权的实体在需要时可访问数据,即攻击者不能占用所有的资源而阻碍授权者的工作。 可控性:可以控制授权范围内的信息流…

生产环境中AI调用的优化:AI网关高价值应用实践

随着越来越多的组织将生成式AI引入生产环境,他们面临的挑战已经超出了初步实施的范畴。如果管理不当,扩展性限制、安全漏洞和性能瓶颈可能会阻碍AI应用的推广。实际问题如用户数据的安全性、固定容量限制、成本管理和延迟优化等,需要创新的解决方案。 本文我们深入探讨了一些…

MobileViT-v1-所有patch内相对位置相同的token之间计算自注意力

paper def my_self(x: torch.Tensor):通过这段代码 可以把每张图片图片中相对位置相同的若干个tokens放到最后两个维度# [B, C, H, W] -> [B, C, n_h, p_h, n_w, p_w] # n_h是高度方向上可以分多少个patch p_h patch的高度 n_w 宽度方向上可以分多少个patch p_w patch的宽…

27. 使用MySQL之全球化和本地化

1. 字符集和校对顺序 数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。因此,MySQL需要适应不同的字符集(不同的字母和字符),适应不同的排序和检索数据的方法。 在讨论多种语言和字符集时,将会遇到以下重要术语:字符集为字母和符号的集合;…

TCP/IP上三层协议

TCP/IP上三层的角色 同一台设备上的进程间通信有多种方式,如管道、消息队列、共享内存、信号等。而不同设备间的进程通信需要网络通信,由于设备具有多样性,因此协商出了一套通用的网络协议。这个网络协议是分层的,每一层都有各自的作用和职责,接下来将依据 “TCP/IP 网络模…

无线部分

AC堆叠(VAC) 配置两台AC设备,使用虚拟化方案组合成1台虚拟AC。 AC1和AC2之间的G 0/3-4端口作为虚拟交换链路。配置AC1为主,AC2为备。主设备 description为AC1,备用设备description为AC2。 AC1 virtual-ac domain 100device 1 device 1 priority 200 device 1 description …

DHCP欺骗

DHCP 欺骗原理DHCP 协议(Dynamic Host Configuration Protocol) 动态主机配置协议:主要给客户机提供 TCP/IP 参数,包括:IP 地址、子网掩码、网关、DNS、租期工作原理应用层协议,基于UDP 主机向服务器 67 号端口发送 DHCP 请求 服务器响应给客户机的 68号端口配置设置DHCP 服…

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error 解决方案: 1、启动redis客户端:redis-cli.exe。 2、执行关闭命令:输入shutdown3、执行退出命令:exit4、重新启动Redis输入:redis-server.exe redis.windows.conf

https实验

https 实验原理httphttps https = http + SSL/TLS •SSL: Secure Socket Layer 安全套接层 •TLS: Transport Layer Security 传输层安全协议加密方式:PKI(公钥基础设施)使用公钥技术和数字签名来保证信息安全由公钥密码算法、数字证书(Certificate)、CA(Certificate Aut…

手把手教你搭建OpenScenario交通场景(上)

经纬恒润动力学仿真软件ModelBase基于OpenScenario1.0标准,开发内嵌了场景编辑器,可用于对仿真测试过程中的车辆行驶道路模型之外,继续进行周边动态场景的搭建。 OpenScenario是一种专为自动驾驶系统仿真测试设计的场景描述语言,它基于XML格式,旨在提供一个标准化、…

动态规划题单2

第一个题单编辑到后面实在是太卡了,就新开了一个,以后应该也会 \(30\) 题为一个题单。 31.CF1580D Subsequence CF1580D Subsequence 不会笛卡尔树,但是看到题解区的妙妙解法...... 题目的式子非常大便,我们考虑把它翻译成人话: 一个子序列的价值为: \(sum*m - 每两个数及他…