# 4990: [Usaco2017 Feb]Why Did the Cow Cross the Road II 线段树维护dp

## 链接

http://www.lydsy.com/JudgeOnline/problem.php?id=4990

n <= 10^5。

## 输入

The first line of input contains N (1≤N≤100,0000).
The next N lines describe the order, by breed ID, of fields on one side of the road;
each breed ID is an integer in the range 1…N
The last N lines describe the order, by breed ID, of the fields on the other side of the road.
Each breed ID appears exactly once in each ordering.

## 输出

Please output the maximum number of disjoint "friendly crosswalks" Farmer John can draw across the road.

6

1

2

3

4

5

6

6

5

4

3

2

1

5

## 题解

dp[i][j]=max(dp[i-1][j],dp[i][j-1])

## 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
int a[maxn],b[maxn],c[maxn],n,dp[maxn];
struct node{int l,r,x;}t[maxn*4];
void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r){t[x].x=0;return;}
int mid=(l+r)/2;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x].x=max(t[x<<1].x,t[x<<1|1].x);
}
void update(int x,int l,int r,int v){
int L=t[x].l,R=t[x].r;
if(l==L&&R==r){
t[x].x=v;
return;
}
int mid=(L+R)/2;
if(mid>=l)update(x<<1,l,r,v);
if(mid<r)update(x<<1|1,l,r,v);
t[x].x=max(t[x<<1].x,t[x<<1|1].x);
}
int query(int x,int l,int r)
{
int L=t[x].l,R=t[x].r;
if(l<=L&&R<=r)return t[x].x;
int ans=0,mid=(L+R)/2;
if(mid>=l)ans=max(ans,query(x<<1,l,r));
if(mid<r)ans=max(ans,query(x<<1|1,l,r));
return ans;
}
int main(){
scanf("%d",&n);
build(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
for(int i=1;i<=n;i++){
c[b[i]]=i;
}
for(int i=1;i<=n;i++){
for(int j=-4;j<=4;j++){
if(a[i]+j>0&&a[i]+j<=n){
dp[c[a[i]+j]]=max(dp[c[a[i]+j]],query(1,1,c[a[i]+j]-1)+1);
}
}
for(int j=-4;j<=4;j++){
if(a[i]+j>0&&a[i]+j<=n){
update(1,c[a[i]+j],c[a[i]+j],dp[c[a[i]+j]]);
}
}
}
cout<<query(1,1,n)<<endl;
}
posted @ 2017-08-29 15:55 qscqesze 阅读(...) 评论(...) 编辑 收藏