【题解】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;
}
posted @ 2025-12-27 09:38  Ming3398  阅读(2)  评论(0)    收藏  举报