【题解】P4093 [HEOI2016/TJOI2016] 序列
【P4093】题解
一:【题意】
略
二:【解法】
记录可能最大值mx,最小值mn
dp[i]=max(dp[j]+1),j<i,mx[j]<=a[i],a[j]<=mn[i]
类似于P3364
三维偏序维护即可
三:【代码】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int tp;
int a,mx,mn;
int dp;
node(){
tp=0;
a=0;
mx=0;
mn=N;
dp=0;
}
}q[N];
bool cmptp(node x,node y){
return x.tp<y.tp;
}
bool cmpmx(node x,node y){
return x.mx<y.mx;
}
bool cmpa(node x,node y){
return x.a<y.a;
}
int tree[N];
void update(int x,int d){
while(x<N){
tree[x]=max(tree[x],d);
x+=x&-x;
}
}
int query(int x){
int res=0;
while(x){
res=max(res,tree[x]);
x-=x&-x;
}
return res;
}
void clear(int x){
while(x<N){
tree[x]=0;
x+=x&-x;
}
}
void CDQ(int l,int r){
if(l==r){
q[l].dp=max(q[l].dp,1);
return ;
}
int mid=l+r>>1;
CDQ(l,mid);
sort(q+l,q+mid+1,cmpmx);sort(q+mid+1,q+r+1,cmpa);
int i=l,j=mid+1;
while(j<=r){
while(i<=mid&&q[i].mx<=q[j].a){
update(q[i].a,q[i].dp);
i++;
}
q[j].dp=max(q[j].dp,query(q[j].mn)+1);
j++;
}
for(int k=l;k<i;k++) clear(q[k].a);
sort(q+mid+1,q+r+1,cmptp);
CDQ(mid+1,r);
}
int main(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
int k;cin>>k;
q[i].a=k;
q[i].mn=q[i].mx=k;
q[i].tp=i;
}
while(m--){
int x,y;cin>>x>>y;
q[x].mn=min(q[x].mn,y);
q[x].mx=max(q[x].mx,y);
}
CDQ(1,n);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,q[i].dp);
cout<<ans<<"\n";
return 0;
}

浙公网安备 33010602011771号