调好久,真的破防了,求佬捞
查看原帖
调好久,真的破防了,求佬捞
760859
Let_Fly楼主2023/8/1 21:16
#include<bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
const int N=5e5+5,mod=998244353;

int n,q,k,cnt;
vector<int> to[N];
int mi[N];
vector<pair<int,pair<int,int> > > que;
struct Tree{
    int tag,sum,cs;
}tr[N<<2];

int dep[N];
int fa[N];
int son[N];
int sz[N];
int top[N];
int id[N];
int fid[N];
// int a[N];
// int b[N];

int ans[N];

void dfs1(int u,int f){
    fa[u]=f;
    dep[u]=dep[f]+1;
    sz[u]=1;
    for(auto v:to[u]){
        if(v==f)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        if(sz[son[u]]<sz[v])son[u]=v;
    }
}

void dfs2(int u,int t){
    id[u]=++cnt;
    fid[cnt]=u;
    // a[cnt]=b[u];
	top[u]=t;
	if(!son[u])return;
	dfs2(son[u],t);
	for(auto v:to[u]){
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}

int qpow(int a,int b){
    int r=1;
    while(b){
        if(b&1)r=1ll*r*a%mod;
        b>>=1,a=1ll*a*a%mod;
    }
    return r;
}

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

void pushdown(int u,int l,int r){
    tr[ls].tag+=tr[u].tag%mod;
    tr[rs].tag+=tr[u].tag%mod;
    int mid=l+r>>1;
    tr[ls].sum=(tr[ls].sum+tr[u].tag*tr[ls].cs%mod)%mod;
    tr[rs].sum=(tr[rs].sum+tr[u].tag*tr[rs].cs%mod)%mod;
    tr[u].tag=0;
}

void build(int u,int l,int r){
    if(l==r){
        tr[u].cs=(mi[dep[fid[l]]]-mi[dep[fid[l]]-1]+mod)%mod;
        // cout<<tr[u].cs;
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    tr[u].cs=(tr[ls].cs+tr[rs].cs+mod)%mod;
}

void update(int u,int k,int l,int r,int L,int R){
    if(l<=L&&R<=r){
        tr[u].sum=(tr[u].sum+tr[u].cs%mod)%mod;
        tr[u].tag+=k%mod;
        return;
    }
    int mid=L+R>>1;
    if(tr[u].tag)pushdown(u,L,R);
    if(l<=mid)update(ls,k,l,r,L,mid);
    if(r>mid)update(rs,k,l,r,mid+1,R);
    pushup(u);
}

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

void ud(int x){
    while(top[x]) update(1,1,id[top[x]],id[x],1,n),x=fa[top[x]];
}

int qr(int u){
    int ans = 0;
    while(top[u]) ans=(ans+query(1,id[top[u]],id[u],1,n))%mod,u=fa[top[u]];
    return ans;
}

int main(){
    cin>>n>>q>>k;
    for(int i=2;i<=n;i++){
        int u;
        cin>>u;
        to[u].push_back(i);
    }
    for(int i=1;i<=n;i++)mi[i]=qpow(i,k);
    for(int i=1;i<=q;i++){
        int x,y;
        cin>>x>>y;
        que.push_back(make_pair(x,make_pair(y,i)));
    }
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    sort(que.begin(),que.end());
    int nw=0;
    for(int i=1;i<=n;i++){
        ud(i);
        while(i==que[nw].first){
            ans[que[nw].second.second]=qr(que[nw].second.first);
            nw++;
        }
    }
    // ans[1]=query(1,2,4,1,n);
    // cout<<tr[1].cs;
    for(int i=1;i<=q;i++){
        cout<<ans[i]<<'\n';
    }
    return 0;
}
2023/8/1 21:16
加载中...