#include<cstdio>
#include<iostream>
#include<algorithm>
#define M 100009
using namespace std;
struct data
{
int x,y,z,f[];
double sum[];
}a[M],b[M];
struct ss
{
int w;
double su;
}shu[M];
int n,yy[M],zz[M],yl,zl,ans,tot,sta[M];
double sum1;
bool cmp(data a1,data a2)
{
if(a1.y==a2.y)
return a1.x<a2.x;
return a1.y<a2.y;
}
bool cmp1(data a1,data a2)
{
return a1.x>a2.x;
}
void updata(int i,int p)
{
int a1=a[i].z;
for(;a1<=zl;a1+=a1&-a1)
if(shu[a1].w<a[i].f[p])
{
if(shu[a1].w==)
sta[++tot]=a1;
shu[a1].w=a[i].f[p];
shu[a1].su=a[i].sum[p];
}
else if(shu[a1].w==a[i].f[p])
shu[a1].su+=a[i].sum[p];
return;
}
void ask(int i,int p)
{
int a1=a[i].z;
for(;a1;a1-=a1&-a1)
if(a[i].f[p]<=shu[a1].w&&shu[a1].w)
{
a[i].f[p]=shu[a1].w+;
a[i].sum[p]=shu[a1].su;
}
else if(a[i].f[p]==shu[a1].w+)
a[i].sum[p]+=shu[a1].su;
return;
}
void solve(int l,int r,int p)
{
if(l==r)
{
if(a[l].f[p]==)
a[l].f[p]=a[l].sum[p]=;
return;
}
int mid=(l+r)>>;
int l1=l,l2=mid+;
for(int i=l;i<=r;i++)
if(a[i].x<=mid)
b[l1++]=a[i];
else
b[l2++]=a[i];
for(int i=l;i<=r;i++)
a[i]=b[i];
solve(l,mid,p);
sort(a+l,a+mid+,cmp);
int st=l;
for(int i=mid+;i<=r;i++)
{
for(;a[st].y<=a[i].y&&st<=mid;st++)
updata(st,p);
ask(i,p);
}
for(int i=;i<=tot;i++)
shu[sta[i]].w=shu[sta[i]].su=;
tot=;
solve(mid+,r,p);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
a[i].x=i;
scanf("%d%d",&a[i].y,&a[i].z);
yy[i]=a[i].y;
zz[i]=a[i].z;
}
sort(yy+,yy+n+);
sort(zz+,zz+n+);
yl=unique(yy+,yy+n+)-yy-;
zl=unique(zz+,zz+n+)-zz-;
for(int i=;i<=n;i++)
{
a[i].y=yl-(lower_bound(yy+,yy+yl+,a[i].y)-yy)+;
a[i].z=zl-(lower_bound(zz+,zz+zl+,a[i].z)-zz)+;
}
sort(a+,a+n+,cmp);
solve(,n,);
for(int i=;i<=n;i++)
{
a[i].x=n-a[i].x+;
a[i].y=yl-a[i].y+;
a[i].z=zl-a[i].z+;
}
sort(a+,a+n+,cmp);
solve(,n,);
sort(a+,a+n+,cmp1);
for(int i=;i<=n;i++)
if(a[i].f[]>ans)
{
ans=a[i].f[];
sum1=a[i].sum[];
}
else if(a[i].f[]==ans)
sum1+=a[i].sum[];
printf("%d\n",ans);
for(int i=;i<=n;i++)
if(a[i].f[]+a[i].f[]-==ans)
printf("%.5lf ",a[i].sum[]*a[i].sum[]/sum1);
else
printf("0.00000 ");
return ;
}
首先第一问明显是一个三维偏序集,速度,高度,时间,用CDQ分治做,然后我们把它反过来,在做一边CDQ分治,这两遍求出来的方案数组相乘,就是过这个点的方案数。