记录编号 364372 评测结果 AAAAAAAAAA
题目名称 [HEOI 2016] 序列 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 2.278 s
提交时间 2017-01-16 10:57:17 内存使用 116.65 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
const double alpha=0.7;
struct node{
	int key,data,mx,size;
	node *ch[2];
	node(int k=1000000,int d=0):key(k),data(d),mx(d),size(1){}
	void refresh(){
		size=ch[0]->size+ch[1]->size+1;
		mx=max(data,max(ch[0]->mx,ch[1]->mx));
	}
	int cmp(int x){return x==key?-1:x>key;}
}pool[maxn*50],*null=pool,*ptr=null,*root[maxn],*nodes[maxn];
void modify(int,int,int);
int query(int,int);
node*& modify(int,int,node*&);
int query(int,node*);
void rebuild(int,int,node*&);
void travel(node*);
int n,m,a[maxn],mn[maxn],mx[maxn],x,y,cnt,tmp,ans=0;
int main(){
	freopen("heoi2016_seq.in","r",stdin);
	freopen("heoi2016_seq.out","w",stdout);
	null->size=0;
	scanf("%d%d",&n,&m);
	fill(root,root+n+1,null);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	copy(a+1,a+n+1,mn+1);
	copy(a+1,a+n+1,mx+1);
	while(m--){
		scanf("%d%d",&x,&y);
		mn[x]=min(mn[x],y);
		mx[x]=max(mx[x],y);
	}
	for(int i=1;i<=n;i++){
		tmp=query(a[i],mn[i])+1;
		ans=max(ans,tmp);
		modify(mx[i],a[i],tmp);
	}
	printf("%d",ans);
	return 0;
}
void modify(int x,int y,int d){
	while(x<=n){
		node *&rt=modify(y,d,root[x]);
		if(rt!=null){
			cnt=0;
			travel(rt);
			rebuild(1,cnt,rt);
		}
		x+=x&-x;
	}
}
int query(int x,int y){
	int ans=0;
	while(x){
		ans=max(ans,query(y+1,root[x]));
		x&=x-1;
	}
	return ans;
}
node *&modify(int x,int y,node *&rt){
	if(rt==null){
		*(rt=++ptr)=node(x,y);
		rt->ch[0]=rt->ch[1]=null;
		return null;
	}
	int d=rt->cmp(x);
	if(d==-1){
		rt->data=max(rt->data,y);
		rt->refresh();
		return null;
	}
	node *&tmp=modify(x,y,rt->ch[d]);
	rt->refresh();
	if(max(rt->ch[0]->size,rt->ch[1]->size)>rt->size*alpha)return rt;
	else return tmp;
}
int query(int x,node *rt){
	int ans=0,d;
	while(rt!=null){
		if((d=rt->key<x))ans=max(ans,max(rt->data,rt->ch[0]->mx));
		rt=rt->ch[d];
	}
	return ans;
}
void rebuild(int l,int r,node *&rt){
	if(l>r){
		rt=null;
		return;
	}
	int mid=(l+r)>>1;
	rt=nodes[mid];
	rebuild(l,mid-1,rt->ch[0]);
	rebuild(mid+1,r,rt->ch[1]);
	rt->refresh();
}
void travel(node *x){
	if(x==null)return;
	travel(x->ch[0]);
	nodes[++cnt]=x;
	travel(x->ch[1]);
}