悬关求调,20pts
查看原帖
悬关求调,20pts
525375
Richard_Whr楼主2023/11/26 17:15
#include<bits/stdc++.h>
#define ls u*2
#define rs u*2+1
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=1e5+10,mod=998244353;
vector<int> e[N];
int dfn[N],sz[N],ts;
int dep[N],fa[N],top[N],son[N],seq[N];
struct node
{
    int l,r;
    int w;
    int sum,add;
}tr[N*4];
int n,m,K;
vector<PII> q[N];
int ans[N];

void add(int u,int c)
{
    tr[u].sum=(tr[u].sum+(tr[u].w*c)%mod)%mod;
    tr[u].add+=c;
}

int qmi(int a,int k,int p)
{
    int res=1;
    while(k)
    {
        if(k&1) res=(res*a)%p;
        a=(a*a)%p;
        k>>=1;
    }
    return res;
}

void pushup(int u)
{
    tr[u].sum=(tr[ls].sum+tr[rs].sum)%mod;
}

void pushdown(int u)
{
    if(tr[u].add)
    {
        add(ls,tr[u].add),add(rs,tr[u].add);
        tr[u].add=0;
    }
}

void build(int u,int l,int r)
{
    tr[u]={l,r,0,0,0};
    if(l==r) 
    {
        tr[u].w=(qmi(dep[seq[l]],K,mod)-qmi(dep[seq[l]]-1,K,mod)+mod)%mod;
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid),build(rs,mid+1,r);
    tr[u].w=(tr[ls].w+tr[rs].w)%mod;
}

void modify(int u,int l,int r,int c)
{
    if(tr[u].l>=l&&tr[u].r<=r) add(u,c);
    else
    {
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid) modify(ls,l,r,c);
        if(r>mid) modify(rs,l,r,c);
        pushup(u);
    }
}

int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
    else
    {
        pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        int res=0;
        if(l<=mid) res=(res+query(ls,l,r))%mod;
        if(r>mid) res=(res+query(rs,l,r))%mod;
        return res;
    }
}

void dfs1(int u,int p,int d)
{
    dep[u]=d,fa[u]=p,sz[u]=1;
    for(auto v:e[u])
    {
        if(v==p) continue;
        dfs1(v,u,d+1);
        sz[u]+=sz[v];
        if(sz[v]>sz[son[u]]) son[u]=v;
    }
}

void dfs2(int u,int t)
{
    dfn[u]=++ts,top[u]=t,seq[dfn[u]]=u;
    if(!son[u]) return;
    dfs2(son[u],t);
    for(auto v:e[u])
    {
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}

void modify_path(int u,int v)
{
    if(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        modify(1,dfn[top[u]],dfn[u],1);
        u=fa[top[u]];
    }
    if(dep[u]<dep[v]) swap(u,v);
    modify(1,dfn[v],dfn[u],1);
}

int query_path(int u,int v)
{
    int res=0;
    if(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        res=(res+query(1,dfn[top[u]],dfn[u]))%mod;
        u=fa[top[u]];
    }
    if(dep[u]<dep[v]) swap(u,v);
    res=(res+query(1,dfn[v],dfn[u]))%mod;
    return res;
}

signed main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m>>K;
    for(int i=2,x;i<=n;i++)
    {
        cin>>x;
        e[x].push_back(i),e[i].push_back(x);
    }
    
    dfs1(1,0,1);
    dfs2(1,1);
    
    build(1,1,n);
    
    
    for(int i=1,x,z;i<=m;i++)
    {
        cin>>x>>z;
        q[x].push_back({z,i});
    }
    
    for(int i=1;i<=n;i++)
    {
        modify_path(1,i);
        for(auto qus:q[i])
        {
            int z=qus.first,id=qus.second;
            ans[id]=query_path(1,z);
        }
    }
    
    for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";
    
    return 0;
}
2023/11/26 17:15
加载中...