线段树+平衡树 beautiful

 

     关于每个值求它的beauty,至多N^2*log(N)的效率,查询一棵线段树搞定。

     那么难点在于求beauty。既然要求一个不断插值的中位数,考虑用平衡树,N^2枚举每一个区间(严格说不是每一个)找中位数。普通treap很轻松。

     那我介绍一种神奇的而且能用set的做法,先膜拜神犇whm。

     对于每个区间的起点,值有一个,然后不断向后推,每次加二,——可以利用这个性质。

     如果加的值全大于当前中位数,那么中位数++,反之,中位数-1。那么这样就弥补了iterator不能进行+=的弊端。

     那么问题又来了,如何将推入的值反射回来呢?

     先离散一下,给每个点的权值赋成一个小的值,并且相同的值编号大的比编号小的大,然后一个back数组反向记录,那个值对应的下标是多少,就OK了。

    

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int read()
{
	int sum=0,f=1;char x=getchar();
	while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
	while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
	return sum*f;
}
struct tree
{
	int l,r,h;
} t[2005*4];
struct node
{
	int id,h;
}a[2005];
int const cmp(const node a,const node b)
{
	return (a.h!=b.h)? (a.h<b.h):(a.id<b.id);
}
int n,h[2005],f[2005],m;
int back[2005];
int check(int x)
{
	set<int> st;
    st.insert(h[x]);
    set<int>::iterator it=st.begin();
    for(int i=x+2;i<=n;i+=2)
    {
    	st.insert(h[i-1]);
    	st.insert(h[i]);
		if(h[i-1]>*it&&h[i]>*it)it++;
		else
		  if(h[i-1]<*it&&h[i]<*it)it--;
    	f[back[*it]]=max(f[back[*it]],i-x+1);
	}
}
void build(int l,int r,int x)
{
	t[x].l=l;t[x].r=r;
	if(l==r)
	{
		t[x].h=f[l];
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,x*2);
	build(mid+1,r,x*2+1);
	t[x].h=max(t[x*2].h,t[x*2+1].h);
}
int q(int l,int r,int x)
{
	if(t[x].l>=l&&t[x].r<=r)
	   return t[x].h;
	int mid=(t[x].l+t[x].r)/2,s=0;
	if(l<=mid)s=q(l,r,x*2);
	if(r>mid)s=max(s,q(l,r,x*2+1));
	return s;
}
int main()
{
	//freopen("beautiful.in","r",stdin);
	//freopen("beautiful.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++){a[i].id=i;a[i].h=read();f[i]=1;}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)h[a[i].id]=i,back[i]=a[i].id;
	for(int i=1;i<=n;i++)check(i); 
	//for(int i=1;i<=n;i++)cout<<f[i]<<" ";
	//cout<<endl;
	build(1,n,1);
	m=read();
	int x,y,ans;
	for(int i=1;i<=m;i++)
	{
		x=read();y=read();
		ans=q(x,y,1);
		printf("%d
",ans);//system("pause");
	}
}

原文地址:https://www.cnblogs.com/QTY2001/p/7632725.html