jzoj3338-[NOI2013模拟]法法塔的奖励【权值线段树,线段树合并】

正题


题目大意

一棵树,对于每个点,求从任何一个在该点的子树为头,以该点为结尾的序列必须选择这个点的最长不降子序列。


解题思路

首先我们使用权值线段树计算答案每个点 ( l , r , w ) (l,r,w) (l,r,w)表示以 l ∼ r l\sim r lr为结尾最长的不降升子序列长度。

然后利用线段树维护,每次跑完子节点之后将线段树合并到父节点上来计算答案。

时间复杂度 O ( n   l o g   n ) O(n\ log\ n) O(n log n)


c o d e code code

#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include
#include
#include
#include
using namespace std;
const int N=101000;
int n,rt[N],tot,ls[N],ans[N],w[N];
struct Edge_node{
	int to,next;
}a[N];
struct Tree_node{
	int w,l,r,lson,rson;
};
vector<int> q[N],c[N];
struct Line_cut_tree{
	Tree_node t[N*20];
	int tot;
	#define ls t[x].lson
	#define rs t[x].rson
	int Ask(int x,int l,int r,int L,int R)
	{
		if(!x) return 0; 
		if(L==l&&R==r)
			return t[x].w;
		int mid=(L+R)/2;
		if(r<=mid) return Ask(ls,l,r,L,mid);
		else if(l>mid) return Ask(rs,l,r,mid+1,R);
		else return max(Ask(ls,l,mid,L,mid),Ask(rs,mid+1,r,mid+1,R));
	}
	void Change(int &x,int pos,int z,int L,int R)
	{
		if(!x) x=++tot;
		if(L==R){
			t[x].w=max(z,t[x].w);
			return;
		}
		int mid=(L+R)/2;
		if(pos<=mid) Change(ls,pos,z,L,mid);
		else if(pos>mid) Change(rs,pos,z,mid+1,R);
		t[x].w=max(t[ls].w,t[rs].w);
	}
	int merge(int x,int y,int L,int R)
	{
		if(!x||!y)
			return x+y;
		t[x].w=max(t[x].w,t[y].w);
		if(L==R)
			return x;
		int mid=(L+R)/2;
		t[x].lson=merge(t[x].lson,t[y].lson,L,mid);
		t[x].rson=merge(t[x].rson,t[y].rson,mid+1,R);
		return x;
	}
	#undef ls
	#undef rs
}Tree;
void addl(int x,int y)
{
	a[++tot].to=y;
	a[tot].next=ls[x];
	ls[x]=tot;
}
void dfs(int x)
{
	int root=0;
	for(int i=ls[x];i;i=a[i].next)
	{
		int y=a[i].to;
		dfs(y);
		root=Tree.merge(root,rt[y],1,n);
	}
	ans[x]=Tree.Ask(root,1,w[x],1,n)+1;
	Tree.Change(root,w[x],ans[x],1,n);
	rt[x]=root;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		if(i==1) continue;
		addl(x,i);
	}
	for(int i=1;i<=n;i++)
	  scanf("%d",&w[i]);
	dfs(1);
	for(int i=1;i<=n;i++)
		printf("%d ",ans[i]);
}

你可能感兴趣的:(数据结构)