제출 #770550

#제출 시각아이디문제언어결과실행 시간메모리
770550amirhoseinfar1385LIS (INOI20_lis)C++17
100 / 100
2525 ms215248 KiB
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int par[maxn],link[maxn],n,dpnah[maxn],inf=1e7,res=0,nt[maxn];
pair<int,int>all[maxn],dov[maxn];

struct lev{
	vector<int>ind;
	vector<int>x;
	int sz=0,kaf;
	struct segmentmaxa{
		int kaf;
		vector<int>seg;
		void ins(int i,int w){
			if(i==0){
				return ;
			}
			seg[i]=max(seg[i],w);
			return ins((i>>1),w);
		}
		void erase(int i){
			if(i==0){
				return ;
			}
			if(i>=kaf){
				seg[i]=0;
			}
			else{
				seg[i]=max(seg[(i<<1)],seg[(i<<1)^1]);
			}
			return erase((i>>1));
		}
		int pors(int i,int l,int r,int tl,int tr,int w){
			if(l>r||l>tr||r<tl||tl>tr)
			{
				return -1;
			}
			if(seg[i]<=w){
				return -1;
			}
			if(l==r){
				return l;
			}
			int m=(l+r)>>1;
			int ret=pors((i<<1),l,m,tl,tr,w);
			if(ret!=-1){
				return ret;
			}
			return pors((i<<1)^1,m+1,r,tl,tr,w);
		}
	}maxa;	

	struct segmentmina{
		int kaf;
		vector<int>seg;
		void ins(int i,int w){
			if(i==0){
				return ;
			}
			seg[i]=min(seg[i],w);
			return ins((i>>1),w);
		}
		void erase(int i){
			if(i==0){
				return ;
			}
			if(i>=kaf){
				seg[i]=inf;
			}
			else{
				seg[i]=min(seg[(i<<1)],seg[(i<<1)^1]);
			}
			return erase((i>>1));
		}
		int pors(int i,int l,int r,int tl,int tr){
			if(l>r||l>tr||r<tl||tl>tr)
			{
				return inf;
			}
			if(l>=tl&&r<=tr){
				return seg[i];
			}
			int m=(l+r)>>1;
			return min(pors((i<<1),l,m,tl,tr),pors((i<<1)^1,m+1,r,tl,tr));
		}
	}mina;	

	void cre(){
		sz=(int)ind.size();
		kaf=nt[sz];
		maxa.seg.resize(kaf*2);
		mina.seg.resize(kaf*2,inf);
		maxa.kaf=kaf;
		mina.kaf=kaf;
	}
	int find(int r){
		int p=upper_bound(ind.begin(),ind.end(),r)-ind.begin();
		p--;
		if(p<0){
			return inf;
		}
		return mina.pors(1,0,kaf-1,0,p);
	}
}lev[maxn];

void updlev(int u,int lv){
	res=max(res,lv);
	int p=lower_bound(lev[lv].ind.begin(),lev[lv].ind.end(),u)-lev[lv].ind.begin();
	lev[lv].maxa.ins(lev[lv].kaf+p,lev[lv].x[p]);
	lev[lv].mina.ins(lev[lv].kaf+p,lev[lv].x[p]);
	while(true){
		int z=lev[lv].maxa.pors(1,0,lev[lv].kaf-1,p+1,lev[lv].sz,lev[lv].x[p]);
		if(z==-1){
			break;
		}
		lev[lv].maxa.erase(lev[lv].kaf+z);
		lev[lv].mina.erase(lev[lv].kaf+z);
		updlev(lev[lv].ind[z],lv+1);
	}
}

void aval(){
	for(int i=0;i<maxn;i++){
		par[i]=i;
	}
	nt[1]=2;
	for(int i=2;i<maxn;i++){
		nt[i]=nt[i/2]*2;
	}
}

int root(int c){
	if(c==par[c]){
		return c;
	}
	return par[c]=root(par[c]);
}

void merge(int u,int v){
	int rootu=root(u),rootv=root(v);
	if(rootu!=rootv){
		par[rootu]=rootv;
	}
}
int kafa=(1<<20);

struct fc{
	int seg[(1<<21)],lazy[(1<<21)];
	fc(){
		for(int i=0;i<(1<<21);i++){
			seg[i]=inf;
		}
	}
	void upd(int i,int w){
		if(i==0){
			return ;
		}
		seg[i]=min(seg[i],w);
		return upd((i>>1),w);
	}
	void calc(int i){
		if(i>=kafa){
			seg[i]+=lazy[i];
			lazy[i]=0;
			return ;
		}
		seg[i]=min(seg[(i<<1)]+lazy[(i<<1)],seg[(i<<1)^1]+lazy[(i<<1)^1]);
	}

	void shift(int i){
		if(lazy[i]==0){
			return ;
		}
		if(i>=kafa){
			return calc(i);
		}
		lazy[(i<<1)]+=lazy[i];
		lazy[(i<<1)^1]+=lazy[i];
		lazy[i]=0;
		calc(i);
	}

	void updsuma(int i,int l,int r,int tl,int tr,int w){
		if(l>r||l>tr||r<tl||tl>tr){
			return ;
		}
		shift(i);
		if(l>=tl&&r<=tr){
			lazy[i]+=w;
			return ;
		}
		int m=(l+r)>>1;
		updsuma((i<<1),l,m,tl,tr,w);
		updsuma((i<<1)^1,m+1,r,tl,tr,w);
		calc(i);
		return ;
	}

	int porsm(int i,int l,int r,int tl,int tr){
		if(l>r||l>tr||r<tl||tl>tr){
			return inf;
		}
		shift(i);
		if(l>=tl&&r<=tr){
		//	cout<<l<<" "<<r<<" "<<seg[i]<<'\n';
			return seg[i];
		}
		int m=(l+r)>>1;
		return min(porsm((i<<1),l,m,tl,tr),porsm((i<<1)^1,m+1,r,tl,tr));
	}
	int porsw(int i,int l,int r,int tl,int tr,int w){
		if(l>r||l>tr||r<tl||tl>tr){
			return -1;
		}
		shift(i);
		if(seg[i]>w){
			return -1;
		}
		if(l==r){
			return l;
		}
		int m=(l+r)>>1;
		int ret=porsw((i<<1)^1,m+1,r,tl,tr,w);
		if(ret==-1){
			ret=porsw((i<<1),l,m,tl,tr,w);
		}	
		return ret;
	}

	int pors(){
		int mina=porsm(1,0,kafa-1,0,maxn);
		//cout<<mina<<endl;
		return porsw(1,0,kafa-1,0,maxn,mina);
	}
}fc;

vector<int>allv[maxn];
void createall(){
	for(int i=1;i<=n;i++){
		fc.upd(kafa+i,all[i].first);
	}
	for(int i=1;i<=n;i++)
	{
		int w=fc.pors();
		//cout<<i<<" "<<w<<"\n";
		fc.updsuma(1,0,kafa-1,w,w,inf);
		dov[i]=make_pair(all[w].second,w);
		link[w]=i;
		fc.updsuma(1,0,kafa-1,0,w,1);
	}
}

void createlis(){
	vector<int>fake;
	for(int i=1;i<=n;i++){
		int p=lower_bound(fake.begin(),fake.end(),dov[i].first)-fake.begin();
		if(p==(int)fake.size()){
			fake.push_back(dov[i].first);
		}
		else{
			fake[p]=dov[i].first;
		}
		dpnah[i]=p+1;
		for(int j=1;j<=p+1;j++){
			lev[j].ind.push_back(i);
			lev[j].x.push_back(dov[i].first);
		}
	}
}

int wtf(int u){
	for(int i=dov[u].first;i>=1;i--){
		if(lev[i].find(u)<dov[u].first){
			return i;
		}
	}
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	aval();
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>all[i].first>>all[i].second;
	}
	createall();
	createlis();
	for(int i=0;i<maxn;i++){
		lev[i].cre();
	}
	for(int i=1;i<=n;i++){
		int ln=wtf(link[i])+1;
	//	cout<<i<<" "<<ln<<" "<<link[i]<<endl;
		updlev(link[i],ln);
		cout<<res<<"\n";
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...