1 条题解

  • 0
    @ 2026-8-26 13:26:49

    LIS 可以用 BIT 维护,但是 BIT 不支持撤销,所以我们改成线段树。

    然后我们就根据值域开栈再 dfs,如果以当前节点为末尾的 LIS 长度超过了栈顶就入栈,遍历完字数后再弹出。

    记得离散化。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    #define lc(p) (p<<1)
    #define rc(p) (p<<1|1)
    struct SMTree
    {
    	struct node{int l,r,mx;}tr[N<<2];
    	void pushup(int p){tr[p].mx=max(tr[lc(p)].mx,tr[rc(p)].mx);}
    	void bt(int p,int l,int r)
    	{
    		tr[p]={l,r,0};
    		if(l==r)return;
    		int mid=(l+r)>>1;
    		bt(lc(p),l,mid);bt(rc(p),mid+1,r);
    		pushup(p);
    	}
    	void change(int p,int x,int k)
    	{
    		if(tr[p].l>x||tr[p].r<x)return ;
    		if(tr[p].l==tr[p].r)
    		{
    			tr[p].mx=k;
    			return;
    		}
    		change(lc(p),x,k);change(rc(p),x,k);
    		pushup(p);
    	}
    	int query(int p,int l,int r)
    	{
    		if(tr[p].l>r||tr[p].r<l)return 0;
    		if(l<=tr[p].l&&tr[p].r<=r)return tr[p].mx;
    		return max(query(lc(p),l,r),query(rc(p),l,r));
    	}
    }tr;
    vector<int>G[N];
    int a[N],ans[N],c[N],b[N];stack<int>stk[N];
    void dfs(int x,int f)
    {
    	c[x]=tr.query(1,1,a[x]-1)+1;
    	ans[x]=max(c[x],ans[f]);
    	bool bk=0;
    	if(ans[x]>stk[a[x]].top())
    	{
    		stk[a[x]].push(c[x]);
    		tr.change(1,a[x],stk[a[x]].top());
    		bk=1;
    	}
    	for(int y:G[x])if(y!=f)
    		dfs(y,x);
    	if(bk)stk[a[x]].pop(),tr.change(1,a[x],stk[a[x]].top());
    }
    signed main()
    {
    	int n;cin>>n;
    	for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
    	sort(b+1,b+n+1);int blen=unique(b+1,b+n+1)-b-1;
    	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+blen+1,a[i])-b; 
    	for(int i=1;i<n;i++)
    	{
    		int x,y;cin>>x>>y;
    		G[x].push_back(y);
    		G[y].push_back(x);
    	}
    	for(int i=1;i<=blen;i++)stk[i].push(0);
    	tr.bt(1,1,blen);
    	dfs(1,0);
    	for(int i=1;i<=n;i++)cout<<ans[i]<<'\n';
    	return 0;
    }

    信息

    ID
    11891
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    7
    已通过
    2
    上传者