最大后缀值个数 本题看看数据范围其实就大概知道怎么做,然后发现是单调的,直接单调栈就行了
本题有个很坑的细节(其实是我打得太烂了,调了很久没跳出来,一直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 (因为只记录了长度改变,没记录值改变)