P3657 题解
是不是有点恶意评分了
Sol
看完题目就想到了这个题。
这道题同样是求线段,不过这个加了点限制,发现一个点最多连 4 条边出去,暴力连边的复杂度是正确的,于是就把这题变成黄了。
利用刚刚那道题的 trick,把边按左端点排序后右端点的 LIS 就是答案。
这里给一个更方便的做法,不用真的去连边,直接扫左端点是自动排序好了的,记录每个编号的位置,然后用树状数组 dp 就好。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
int n;
int a[N], b[N], p[N], f[N];
int c[N];
void modify(int x, int v) {
for(; x <= n; x += x & -x) c[x] = max(c[x], v);
}
int query(int x) {
int res = 0;
for(; x; x -= x & -x) res = max(res, c[x]);
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i = 1; i <= n; i ++) {
cin >> a[i];
}
for(int i = 1; i <= n; i ++) {
cin >> b[i];
p[b[i]] = i;
}
for(int i = 1; i <= n; i ++) {
queue<int> tmp;
for(int j = max(1, a[i] - 4); j <= min(n, a[i] + 4); j ++)
tmp.push(query(p[j] - 1) + 1);
for(int j = max(1, a[i] - 4); j <= min(n, a[i] + 4); j ++)
modify(p[j], tmp.front()), tmp.pop();
}
cout << query(n) << '\n';
return 0;
}
注意 dp 的过程中不能刚查询完就改,需要把
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现