首先要求的式子是一個斜率的相反數,其實就是求斜率的最大值,那麼我們只需維護一個下凸包即可,
考慮到直接用棧來存,如果是在一條鏈上的話可以保證每個數只會被插入彈出一次,直接做,暴力退棧就行了。
然而在樹上暴力退的話會被卡成O(
所以對於每個點存一個倍增數組,記錄其在凸殼裏的祖先,然後亂搞即可……
代碼:
//#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <limits>
#include <map>
#include <vector>
#include <queue>
#define LL long long
#define ft first
#define sd second
#define mp(x,y) make_pair(x,y)
#define db double
//#define int LL
using namespace std;
const int N = 5e5+10;
//const int mod = ;
const db INF =numeric_limits<double >::max();
#define rep(i,x,y) for (int i=x;i<=y;++i)
void read(int &x)
{
x=0;
char ch=getchar();
int f=1;
while (!isdigit(ch))
(ch=='-'?f=-1:0),ch=getchar();
while ( isdigit(ch)) x=x*10+ch-'0',ch=getchar();
x*=f;
}
int c[N],fa[N],dep[N];
int head[N];
struct xx
{
int V,next;
}b[N<<1];
int G,n;
void add(int x,int y)
{
b[++G]=(xx){y,head[x]};
head[x]=G;
}
db f[N];
#define F(x) for (int i=head[x];i;i=b[i].next)
#define v b[i].V
int q[N],hd,tl,nw;
int anc[N][20],x;
int ok(int xi,int yi,int xj,int yj,int xk,int yk)
{
return (LL)(yj-yi)*(LL)(xk-xj)<=(LL)(yk-yj)*(LL)(xj-xi);
}
signed main()
{
freopen("data.txt","r",stdin);
freopen("Moon.txt","w",stdout);
read(n);
rep(i,1,n)
read(c[i]);
rep(i,2,n) read(fa[i]),add(fa[i],i);
//dfs(1,0);
q[1]=1;hd=tl=1;
while (hd<=tl)
{
nw=q[hd++];dep[nw]=dep[fa[nw]]+1;
F(nw) q[++tl]=v;
if (nw==1) continue;
x=fa[nw];
for (int i=2;i>=0;--i)
{
if (anc[ x][i]<=1) continue;
if (!ok(dep[ anc[anc[x][i]][0] ],c[ anc[anc[x][i]][0] ],dep[anc[x][i]],c[anc[x][i]],dep[nw],c[nw]))
x=anc[x][i];
}
if (x>1)
if (!ok(dep[anc[x][0]],c[anc[x][0]],dep[x],c[x],dep[nw],c[nw]))
x=anc[x][0];
anc[nw][0]=x;
rep(i,1,19) anc[nw][i]=anc[anc[nw][i-1]][i-1];
}
rep(i,2,n) printf("%.10f\n",(db)(c[anc[i][0]]-c[i])/(dep[i]-dep[anc[i][0]]));
return 0;
}