思路:用树剖存一条链上的最小值,在用 n2 的方法求,如果最小值比当前点小就一步一步往上跳更新。(会t几个点但是应该卡的过)
#include<bits/stdc++.h>
using namespace std;
struct node
{
int nxt,to;
}e[114514*4];
int head[114514*2],cnt;
void add(int u,int v)
{
e[++cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int n,a[114514*2],f[114514*2],dp[114514*2],ans[114514*2];
int dep[114514*2],top[114514*2],sie[114514*2],son[114514*2],minn[114514*2];
void dfs1(int u,int fa)
{
f[u]=fa;
dep[u]=dep[fa]+1;
sie[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=fa)
{
dfs1(v,u);
sie[u]+=sie[v];
if(sie[son[u]]<sie[v])
son[u]=v;
}
}
}
void dfs2(int u,int t,int p)
{
top[u]=t;
if(a[u]<a[p])
p=u;
minn[top[u]]=p;
if(son[u])
dfs2(son[u],t,p);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=f[u]&&v!=son[u])
dfs2(v,v,v);
}
}
//dp[i]=max(dp[j]+1) if(a[i]<a[j])
void dfs(int u)
{
int x=u;
// cout<<u<<' '<<dp[u]<<endl;
do
{
if(a[minn[top[x]]]<a[u])
{
int p=x;
while(p!=top[x])
{
//cout<<p<<" "<<top[x]<<" "<<u<<endl;
if(a[p]<a[u])
dp[u]=max(dp[u],dp[p]+1);
p=f[p];
}
}
if(top[x]!=1)
x=f[top[x]];
}while(top[x]!=1);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v!=f[u])
dfs(v);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
a[0]=1e10;
dfs1(1,0);
dfs2(1,1,1);
// for(int i=1;i<=n;i++)
// cout<<top[i]<<" "<<minn[top[i]]<<endl;
// for(int i=1;i<=n;i++)
// cout<<f[i]<<" ";
for(int i=1;i<=n;i++)
dp[i]=1;
dfs(1);
for(int i=1;i<=n;i++)
cout<<dp[i]<<endl;
}