【BZOJ】【P2225】【Spoj 2371】【Another Longest Increasing】【树套树】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2225

树状数组维护一维,bst维护另一维

好像有nlogn做法……

于是垫底倒数第一

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int getint(){
	int res=0,f=1;char c=getchar();
	while(!isdigit(c))f=f==-1||c=='-'?-1:1,c=getchar();
	while(isdigit(c))res=res*10+c-'0',c=getchar();
	return res*f;
}
int n,tot;
struct pii{
	int first,second;
	pii(int x=0,int y=0):first(x),second(y){}
	bool operator==(pii oth)const{return first==oth.first&&second==oth.second;}
	bool operator<(pii oth)const{return first<oth.first||(first==oth.first&&second>oth.second);}
};
pii a[maxn];
map<int,int>M;
struct node{
	int key,mx,size;
	pii val;
	node *c[2];
	node(pii _val=pii(0,0),node *C=0){
		val=_val;key=rand();mx=_val.second;
		c[0]=c[1]=C;size=1;
	}
	void rz(){
		size=c[0]->size+1+c[1]->size;
		mx=max(c[0]->mx,val.second);
		mx=max(c[1]->mx,mx);
	}
}*Null,pool[maxn*15];
node *newnode(pii _val=pii(0,0),node *C=0){
	static int tot=0;
	if(tot<maxn*15){
		pool[tot].val=_val;pool[tot].key=rand();pool[tot].mx=_val.second;
		pool[tot].c[0]=pool[tot].c[1]=C;pool[tot].size=1;
		return &pool[tot++];
	}else return new node(_val,C);
}
struct Treap{
	node *root;
	void init(){
		root=Null;
	}
    void rot(node *&t,bool d){  
        node *p=t->c[d];t->c[d]=p->c[!d];  
        p->c[!d]=t;t->rz();p->rz();t=p;  
    }  
	void _insert(node *&t,pii p){
		if(t==Null){t=newnode(p,Null);return;}
		if(t->val==p)return ;
		_insert(t->c[t->val<p],p);
		if(t->c[t->val<p]->key<t->key)
		rot(t,t->val<p);else t->rz();
	}
	int _Qmax(node *t,int p){
		int ans=0;
		while(t!=Null){
			if(t->val.first<p){
				ans=max(ans,max(t->c[0]->mx,t->val.second));
				t=t->c[1];
			}else t=t->c[0];
		}return ans;
	}
	void deb(node *t){
		if(t!=Null)
		printf("first:%d second:%d mx:%d size:%d\n",t->val.first,t->val.second,t->mx,t->size);
		if(t->c[0]!=Null)printf("L: "),deb(t->c[0]);
		if(t->c[1]!=Null)printf("R: "),deb(t->c[1]);
	}
	void deb(){deb(root);puts("");}
	void insert(pii p){_insert(root,p);}
	int Qmax(int p){return _Qmax(root,p);}
}T[maxn];
inline int lowbit(int x){return x&-x;}
void updata(int x,pii p){
	while(x<=tot)T[x].insert(p),x+=lowbit(x);
}
int Qmax(int x,int p){
	int ans=0;
	for(int i=x;i;i-=lowbit(i)){
		ans=max(ans,T[i].Qmax(p));	
	}return ans;
}
int ans;
int main(){
	Null=new node(pii(0,0),0);
	Null->size=0;Null->key=INT_MAX;
	Null->c[0]=Null->c[1]=Null;
	n=getint();
	for(int i=1;i<=n;i++){
		a[i].first=getint();a[i].second=getint();
		M[a[i].first]=1;
	}for(map<int,int>::iterator it=M.begin();it!=M.end();it++)it->second=++tot;
	for(int i=1;i<=tot;i++)T[i].init();
	for(int i=1;i<=n;i++)a[i].first=M[a[i].first];
	for(int i=1;i<=n;i++){
		int res=Qmax(a[i].first-1,a[i].second)+1;
		updata(a[i].first,pii(a[i].second,res));
		ans=max(ans,res);
	}cout<<ans<<endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值