本人不擅长卡常,能不能帮我改一下代码,站外题求助。卡过悬 5 关。改完发我我交交试试。
#include<bits/stdc++.h>
#define lc p<<1
#define rc p<<1|1
using namespace std;
const int maxn=5e5+5;
struct edge{
int to,nxt;
} e[maxn];
struct node{
int a,b,c,d;
} p[maxn];
struct line{
int x,id,mark;
} l[maxn*4];
struct Tree{
int l,r,len,sum;
} tree[maxn<<3];
int n,q,head[maxn],cnt,dfn[maxn],siz[maxn],num,L,ans[maxn],f[maxn];
void add_edge(int u,int v){
e[++cnt]={v,head[u]};
head[u]=cnt;
}
void dfs(int u){
siz[u]=1,dfn[u]=++num;f[num]=u;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
dfs(v);
siz[u]+=siz[v];
}
}
bool cmp(line x,line y){return x.x<y.x;}
void build(int l,int r,int p=1){
if(l==r){
tree[p]={l,r,0,0};
return;
}
int mid=l+r>>1;
build(l,mid,lc);
build(mid+1,r,rc);
tree[p]={l,r,0,0};
}
void pushup(int p){
if(tree[p].sum) tree[p].len=tree[p].r-tree[p].l+1;
else tree[p].len=tree[lc].len+tree[rc].len;
}
void add(int l,int r,int v,int p=1){
if(tree[p].l>=l&&tree[p].r<=r){
tree[p].sum+=v;
pushup(p);
return;
}
if(tree[lc].r>=l) add(l,r,v,lc);
if(tree[rc].l<=r) add(l,r,v,rc);
pushup(p);
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1,u;i<n;i++){
cin>>u;
add_edge(u,i+1);
}
dfs(1);
for(int i=1,a,b;i<=q;i++){
cin>>a>>b;
p[i]={dfn[a],dfn[a]+siz[a]-1,dfn[b],dfn[b]+siz[b]-1};
l[++L]={dfn[a],i,1},l[++L]={dfn[a]+siz[a],i,-1};
l[++L]={dfn[b],i,1},l[++L]={dfn[b]+siz[b],i,-1};
}
sort(l+1,l+1+L,cmp);
build(1,n+1);
for(int i=1;i<L;i++){
add(p[l[i].id].a,p[l[i].id].b,l[i].mark);
add(p[l[i].id].c,p[l[i].id].d,l[i].mark);
for(int j=l[i].x;j<l[i+1].x;j++){
ans[f[j]]=max(0,tree[1].len-1);
}
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
return 0;
}