是不是有点恶意评分了
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 的过程中不能刚查询完就改,需要把 \(i\) 能找到的所有记录下来最后一起改,不然可能会计算从 \(i\) 有两条出边的答案。
标签:typedef,const,int,题解,P3657,long,端点 From: https://www.cnblogs.com/Svemit/p/17783908.html