树剖求k级祖先+树上启发式合并WA求助
查看原帖
树剖求k级祖先+树上启发式合并WA求助
177000
vicky2048_2楼主2023/1/13 15:48

之前数组开小了反馈回来TLE调了半个星期,后面一个好心的奆佬帮我调到凌晨发现我数组开小了QwQ

再后面拍了一上午没拍出来就弃疗了QAQ

今天又有一个同市的奆佬帮我看了一下,~~虽然还是没看出来哪错了,~~但是觉得这么多人帮我看了还不A的话过意不去,所以暂时不弃疗了QwQ

目前可以确定树剖求k级祖先没问题,时间复杂度没问题,树上启发式合并眼查+对拍似乎没问题QwQ

所以到底哪里有问题啊啊啊啊啊啊!!!!

#include<bits/stdc++.h>
#define ll long long
#define v to[i]
using namespace std;
const ll M=9000005;
ll n,m,cnt,pos,ans[M],e[M<<1],to[M<<1],fir[M],fa[M],son[M],sz[M],de[M],note[M],top[M],p[M],fp[M];
struct node{
    short bh;
    ll num;
};
vector<node>ask[M];
void add(ll,ll),change(ll,ll),dfs1(ll),dfs2(ll,ll),dfs(ll);
ll f(ll,ll);
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&fa[i]),add(i,fa[i]);
    for(int i=1;i<=n;i++){
        if(fa[i]==0)
            de[i]=1,dfs1(i);
    }
    for(int i=1;i<=n;i++){
        if(fa[i]==0)
            dfs2(i,i);
    }
    scanf("%lld",&m);
    for(int i=1;i<=m;i++){
        ll a,b,as;
        scanf("%lld%lld",&a,&b);
        if(de[a]<=b) continue;
        as=f(a,b);
        node aa; aa.bh=i,aa.num=b;
        ask[as].push_back(aa);
    }
    for(int i=1;i<=n;i++){
        if(fa[i]==0)
            dfs(i),change(i,-1);
    }
    for(int i=1;i<=m;i++) printf("%lld ",ans[i]);
    return 0;
}
void add(ll a,ll b){
    e[++cnt]=fir[a],to[cnt]=b,fir[a]=cnt;
    e[++cnt]=fir[b],to[cnt]=a,fir[b]=cnt;
}
void dfs1(ll no){
    ++sz[no];
    ll maxx=0;
    for(int i=fir[no];i;i=e[i]){
        if(v!=fa[no]){
            de[v]=de[no]+1;
            dfs1(v);
            sz[no]+=sz[v];
            if(sz[v]>maxx)
                maxx=sz[v],son[no]=v;
        }
    }
}
void dfs2(ll no,ll t){
    top[no]=t,p[no]=++pos,fp[pos]=no;
    if(!son[no])
        return;
    dfs2(son[no],t);
    for(int i=fir[no];i;i=e[i]){
        if(v!=fa[no]&&v!=son[no])
            dfs2(v,v);
    }
}
void dfs(ll no){
    for(int i=fir[no];i;i=e[i]){
        if(v!=fa[no]&&v!=son[no])
            dfs(v),change(v,-1);
    }
    if(son[no])
        dfs(son[no]);
    ++note[de[no]];
    for(int i=fir[no];i;i=e[i]){
        if(v!=fa[no]&&v!=son[no])
            change(v,1);
    }
    ll a1=ask[no].size();
    for(int i=0;i<a1;i++)
        ans[ask[no][i].bh]=note[ask[no][i].num+de[no]]-1;
}
void change(ll no,ll k){
    note[de[no]]+=k;
    for(int i=fir[no];i;i=e[i]){
        if(v!=fa[no])
            change(v,k);
    }
}
ll f(ll no,ll k) {
    int d = de[no] - k;
    while (de[top[no]] > d) no = fa[top[no]];
    d = de[no] - d;
    return fp[p[no] - d];
}
2023/1/13 15:48
加载中...