[BZOJ4993||4990] [Usaco2017 Feb]Why Did the Cow Cross the Road II(DP + 线段树)

传送门

 

f[i][j]表示当前第i个,且最后一个位置连接到j

第一维可以省去,能连边的点可以预处理出来,dp可以用线段树优化

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 100001
#define root 1, 1, n
#define ls now << 1, l, mid
#define rs now << 1 | 1, mid + 1, r

using namespace std;

int n, ans, cnt;
int a[N], pos[N], sum[N << 2], f[N];

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
	return x * f;
}

inline int query(int now, int l, int r, int x, int y)
{
	if(x > y) return 0;
	if(x <= l && r <= y) return sum[now];
	int mid = (l + r) >> 1, ret = 0;
	if(x <= mid) ret = max(ret, query(ls, x, y));
	if(mid < y) ret = max(ret, query(rs, x, y));
	return ret;
}

inline void update(int now, int l, int r, int x, int d)
{
	if(l == r)
	{
		sum[now] = max(sum[now], d);
		return;
	}
	int mid = (l + r) >> 1;
	if(x <= mid) update(ls, x, d);
	else update(rs, x, d);
	sum[now] = max(sum[now << 1], sum[now << 1 | 1]);
}

int main()
{
	int i, j, x;
	n = read();
	for(i = 1; i <= n; i++) x = read(), pos[x] = i;
	for(i = 1; i <= n; i++)
	{
		cnt = 0;
		x = read();
		for(j = max(1, x - 4); j <= min(n, x + 4); j++) a[++cnt] = pos[j];
		sort(a + 1, a + cnt + 1);
		for(j = cnt; j >= 1; j--)
		{
			x = query(root, 1, a[j] - 1) + 1;
			f[a[j]] = max(f[a[j]], x);
			update(root, a[j], x);
		}
	}
	for(i = 1; i <= n; i++) ans = max(ans, f[i]);
	printf("%d\n", ans);
	return 0;
}

  

posted @ 2017-09-21 14:59  zht467  阅读(146)  评论(0编辑  收藏  举报