Run ID 作者 问题 语言 测评结果 分数 时间 内存 代码长度 提交时间
1927 16级钟煜奇 【S】T1最大后缀值个数 C++ 解答错误 0 382 MS 90108 KB 1494 2020-11-17 08:28:39

Tests(0/10):


//给定一棵树,求根到每个点的有向链上后缀最大值的个数 //考虑链上的情况,实际上只需要扫右端点的时候维护一个单调栈,单调栈中还剩下的元素个数就是后缀最大值的个数;换到树上我们还需要回溯,考虑每次加入一个点只更改他应该在的位置的数,把新的栈顶传到下一个数,最后再把该位置的数改回来就可以完整地把栈改回来了 #include <iostream> #include <cstdio> using namespace std; const int MAX=1e6+5; int sta[MAX],ans[MAX]; int nxt[MAX<<1],to[MAX<<2],head[MAX],cnt; inline void add(int x,int y){ ++cnt; nxt[cnt]=head[x],to[cnt]=y,head[x]=cnt; ++cnt; nxt[cnt]=head[y],to[cnt]=x,head[y]=cnt; } int value[MAX],fa[MAX]; int n; inline int find(int x,int r){ int l=0,mid,ret; while(l<=r){ mid=(l+r)>>1; if(sta[mid]<x)ret=mid,r=mid-1; l=mid+1; } return ret; } void dfs(int now,int father,int tp){ //cout<<now<<" "<<tp<<endl; ans[now]=tp; for(int aim,i=head[now];i;i=nxt[i]){ aim=to[i]; if(aim!=father){ int pl=find(value[aim],tp); int cpy=sta[pl]; if(pl==0)sta[++tp]=value[aim]; else sta[pl]=value[aim]; dfs(aim,now,tp);// if(pl==0)tp--; else sta[pl]=cpy; } } } signed main(){ scanf("%d",&n); for(int i=2;i<=n;i++)scanf("%d",&fa[i]),add(i,fa[i]); for(int i=1;i<=n;i++)scanf("%d",&value[i]); sta[1]=value[1]; dfs(1,1,1); for(int i=1;i<=n;i++)printf("%d ",ans[i]); return 0; }


测评信息: