记录编号 45963 评测结果 AAAAAAAAAA
题目名称 [NOIP 2010冲刺十二]奶牛排队 最终得分 100
用户昵称 GravatarMakazeu 是否通过 通过
代码语言 C++ 运行时间 0.244 s
提交时间 2012-10-26 00:18:14 内存使用 0.69 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN=100010;
int INF,N,Num[MAXN],ans=0;

class SegTree
{
public:
	int l,r,mid,maxp,minp; SegTree *lc,*rc;
	void clear(){maxp=0,minp=0,lc=NULL,rc=NULL;}
}*Root;

inline void init()
{
	scanf("%d\n",&N);
	for(int i=1;i<=N;i++) 
		scanf("%d",&Num[i]);
	INF=*max_element(Num+1,Num+1+N);INF++;
	Root=new SegTree;
}

void build(SegTree *pnt,int l,int r)
{
	pnt->l=l,pnt->r=r,pnt->mid=(l+r)/2;
	if(l==r) {pnt->maxp=l,pnt->minp=r;return;}
	pnt->lc=new SegTree; build(pnt->lc,l,pnt->mid);
	pnt->rc=new SegTree; build(pnt->rc,pnt->mid+1,r);
	if(Num[pnt->lc->maxp]>=Num[pnt->rc->maxp]) 
		pnt->maxp=pnt->lc->maxp;
		else pnt->maxp=pnt->rc->maxp;
	if(Num[pnt->rc->minp]<=Num[pnt->lc->minp])
		pnt->minp=pnt->rc->minp;
		else pnt->minp=pnt->lc->minp;	
}

int FindMax(SegTree *pnt,int l,int r)
{
	if(pnt->l==l&&pnt->r==r) return pnt->maxp;
	if(r<=pnt->mid) return FindMax(pnt->lc,l,r);
	if(l>=pnt->mid+1) return FindMax(pnt->rc,l,r);
	int a=FindMax(pnt->lc,l,pnt->mid);
	int b=FindMax(pnt->rc,pnt->mid+1,r);
	if(Num[a]>=Num[b]) return a;return b;
}
int FindMin(SegTree *pnt,int l,int r)
{
	if(pnt->l==l&&pnt->r==r) return pnt->minp;
	if(r<=pnt->mid) return FindMin(pnt->lc,l,r);
	if(l>=pnt->mid+1) return FindMin(pnt->rc,l,r);
	int a=FindMin(pnt->lc,l,pnt->mid);
	int b=FindMin(pnt->rc,pnt->mid+1,r);
	if(Num[b]<=Num[a]) return b;return a;
}

void dfs(int l,int r)
{
	if(l>=r) return;
	int big=FindMax(Root,l,r);
	int small=FindMin(Root,l,r);
	if(big>small) 
	{
		if(big-small+1>ans) ans=big-small+1;
		dfs(l,small); dfs(big,r); return;
	}
	if(big==small) return;
	dfs(l,big); dfs(big+1,small-1); dfs(small+1,r);
}

int main()
{
	freopen("tahort.in","r",stdin);
	freopen("tahort.out","w",stdout);
	init(); build(Root,1,N); dfs(1,N);
	printf("%d\n",ans);
	return 0;
}