CDQ死活过不了求迢,悬赏1~2关
查看原帖
CDQ死活过不了求迢,悬赏1~2关
734533
封禁用户楼主2023/7/21 19:56

能过样例,但是没什么*用pwp

//a[i].id<a[j].id,a[i].x<a[j].x,a[i].y<a[j].y
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=4e5+10;
int n;
struct node{
	int id,x,y;
}a[N];
int b[N];//用于离散化
bool cmp1(node a,node b){//处理第一维
	if(a.id!=b.id) return a.id<b.id;
	//下面的可以省略
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}
bool cmp2(node a,node b){//处理第二维
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}
int tr[N],f[N];
void add(int x,int y){
	while(x<=n+10){
		tr[x]=max(tr[x],y),x+=x&(-x);
	}
}
int query(int x){
	int ans=0;
	while(x){
		ans=max(ans,tr[x]),x-=x&(-x);
	}
	return ans;
}
void clr(int x){
	while(x<=n+10){
		tr[x]=0,x+=x&(-x);
	}
}
void cdq(int l,int r){
	if(l==r) return;
	int mid=l+r>>1;
	cdq(l,mid),cdq(mid+1,r);
	sort(a+l,a+mid+1,cmp2),sort(a+mid+1,a+r+1,cmp2);
	int i=l,j=mid+1;
	for(;j<=r;j++){
		while(a[i].x<a[j].x&&i<=mid){//第一维保证的情况下,第二维满足
			add(a[i].y,f[a[i].id]),i++;//处理第三维
		}
		f[a[j].id]=max(f[a[j].id],query(a[j].y-1)+1);
	}
	for(j=l;j<=r;j++){
		clr(a[j].y);
	}
}
int maxx;
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int x,y;cin>>x>>y;
		a[i]={i,x,y};
		b[i]=y,f[i]=1;
	}
	sort(b+1,b+n+1);
	int idx=unique(b+1,b+n+1)-(b+1);
	for(int i=1;i<=n;i++){
		a[i].y=lower_bound(b+1,b+idx+1,a[i].y)-b;
//		cout<<a[i].y<<" ";
	}
	sort(a+1,a+n+1,cmp1);//id保证有序,可以不要
	cdq(1,n);
	for(int i=1;i<=n;i++){
		maxx=max(maxx,f[i]);
	}
	return cout<<maxx<<"\n",0;
}
2023/7/21 19:56
加载中...