最大后缀值个数

    科技2023-10-16  100

    最大后缀值个数 本题看看数据范围其实就大概知道怎么做,然后发现是单调的,直接单调栈就行了

    本题有个很坑的细节(其实是我打得太烂了,调了很久没跳出来,一直80分)

    #include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n; int val[N],f[N],head[N],tnt=0; struct edge{ int link,v; }q[N<<1]; void put(int x,int y){ q[++tnt].v=y; q[tnt].link=head[x]; head[x]=tnt; } int ans[N],mly[N],cnt; int find(int l,int r,int vall){ while(l<r){ int mid=(l+r)>>1; if(mly[mid]>=vall){ l=mid+1; } else r=mid; } return l; } void dfs(int s,int fa){ for(int i=head[s];i;i=q[i].link){ int v=q[i].v; if(v==fa) continue; int tp=cnt,tp2=-1,id=-1; if(val[v]>mly[cnt]){ id=find(1,cnt,val[v]); tp2=mly[id]; mly[id]=val[v]; cnt=id; } else { id=cnt+1,tp2=mly[cnt+1]; mly[++cnt]=val[v]; } dfs(v,s); if(tp2!=-1&&id!=-1){mly[id]=tp2;} cnt=tp; } ans[s]=cnt; } int main(){ scanf("%d",&n); for(int i=2;i<=n;i++){ scanf("%d",&f[i]); put(f[i],i); } for(int i=1;i<=n;i++){ scanf("%d",&val[i]); } mly[1]=val[1],cnt=1; dfs(1,0); for(int i=1;i<=n;i++){ printf("%d ",ans[i]); } } ```AC代码 id=cnt+1,tp2=mly[cnt+1];这段很重要,直接思路是因为原来的串没有这个值(因为原串长小于现在串长),所以不用记录,但实际情况是由于前面有记录,所以如果不修改也会爆

    数据 41 1 1 2 1 1 5 2 5 1 10 1 10 3 1 7 5 15 2 11 13 10 5 16 17 19 13 11 14 20 1 9 27 16 3 23 7 19 15 38 7 11 9 1 9 5 12 13 9 11 1 1 6 12 1 16 1 1 17 5 11 11 8 17 5 5 8 1 11 15 5 17 1 17 1 16 3 1 3 13 11 3

    以本图为例,到10节点为[11,1],到13为[12],到12为[12,11] 回溯回来就变成11,11 (因为只记录了长度改变,没记录值改变)

    Processed: 0.010, SQL: 8