[USACO17FEB]Why Did the Cow Cross the Road II
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4990
[算法]
首先记录b中每个数的出现位置 , 记为P
对于每个ai , 枚举(ai - 4) - (ai + 4) , 将Pj从大到小加入序列
然后求最长上升子序列即可 , 详见代码
时间复杂度 : O(NlogN)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 1000010 int n , len; int a[MAXN] , pos[MAXN] , tmp[MAXN] , f[MAXN] , value[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } struct BinaryIndexedTree { int c[MAXN]; inline int lowbit(int x) { return x & (-x); } inline int query(int x) { int ret = 0; for (int i = x; i; i -= lowbit(i)) chkmax(ret , c[i]); return ret; } inline void modify(int x , int val) { int ret = 0; for (int i = x; i <= n; i += lowbit(i)) chkmax(c[i] , val); } } BIT; int main() { read(n); for (int i = 1; i <= n; i++) read(a[i]); for (int i = 1; i <= n; i++) { int x; read(x); pos[x] = i; } for (int i = 1; i <= n; i++) { int l = 0; for (int j = max(a[i] - 4 , 1); j <= min(a[i] + 4 , n); j++) tmp[++l] = pos[j]; sort(tmp + 1,tmp + l + 1,greater<int>()); for (int j = 1; j <= l; j++) value[++len] = tmp[j]; } int ans = 0; for (int i = 1; i <= len; i++) { f[i] = BIT.query(value[i] - 1) + 1; BIT.modify(value[i] , f[i]); chkmax(ans , f[i]); } printf("%d\n",ans); return 0; }