題目鏈接:LIS on Tree
最開始以爲要以某個點結尾,然後一直wa,其實是跟到這個點路徑上的任意最大LIS。
顯然我們就和普通求LIS一樣,維護一個權值數據結構,然後區間查詢維護。
因爲是路徑上,所以 res[x] =max ( res[fa] , val )
現在是一棵樹,每次回溯的時候取消操作即可。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],res[N],mx[N<<2],m;
vector<int> g[N],v;
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
#define mid (l+r>>1)
void change(int p,int l,int r,int x,int v){
if(l==r){mx[p]=v; return ;}
if(x<=mid) change(p<<1,l,mid,x,v);
else change(p<<1|1,mid+1,r,x,v);
mx[p]=max(mx[p<<1],mx[p<<1|1]);
}
int ask(int p,int l,int r,int ql,int qr){
if(ql>qr) return 0;
if(l==ql&&r==qr) return mx[p];
if(qr<=mid) return ask(p<<1,l,mid,ql,qr);
else if(ql>mid) return ask(p<<1|1,mid+1,r,ql,qr);
else return max(ask(p<<1,l,mid,ql,mid),ask(p<<1|1,mid+1,r,mid+1,qr));
}
void dfs(int x,int fa){
int pre=ask(1,1,m,a[x],a[x]);
int val=max(ask(1,1,m,1,a[x]-1)+1,pre);
res[x]=max(res[fa],val); change(1,1,m,a[x],val);
for(auto to:g[x]) if(to!=fa) dfs(to,x);
change(1,1,m,a[x],pre);
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]);
for(int i=1,a,b;i<n;i++) scanf("%d %d",&a,&b),add(a,b);
sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); m=v.size();
for(int i=1;i<=n;i++) a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
dfs(1,1);
for(int i=1;i<=n;i++) printf("%d\n",res[i]);
return 0;
}