比赛 THUPC 2025 pre 评测结果 RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
题目名称 骑行计划 最终得分 0
用户昵称 123 运行时间 5.751 s
代码语言 C++ 内存使用 3.40 MiB
提交时间 2026-01-29 19:01:26
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10,M=5e5+2;
int n,m,r,w[N],idx[N*2],nxt[N*2],head[N],tot=0,s[N],dfn[N*2],a[N*2],siz[N],id[N],t=0,f[N],fat[N],depth[N],ans[N],mod=998244353,k;
long long b[N];
long long qpow(int x,int y)
{
	long long ret=1,cnt=x;
	while (y)
	{
		if (y%2==1) ret=ret*cnt%mod;
		cnt=cnt*cnt%mod;
		y/=2;
	}
	return ret;
}
struct node {
	int l,r;
	long long ret,flag;
} tr[N*8];
struct qwq {
	int l,q,num;
} e[N];
void add(int x,int y)
{
	idx[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void dfs1(int now,int fa)
{
	depth[now]=depth[fa]+1,siz[now]=1,fat[now]=fa;
	int cnt=0;
	for (int i=head[now];i;i=nxt[i])
	{
		int y=idx[i];
		if (y==fa) continue;
		dfs1(y,now);
		siz[now]+=siz[y];
		if (siz[y]>cnt) cnt=siz[y],s[now]=y;
	}
}
void dfs2(int now,int fa,int tp)
{
	id[now]=++t,a[t]=w[now],f[now]=tp;
	if (!s[now]) return ;
	dfs2(s[now],now,tp);
	for (int i=head[now];i;i=nxt[i])
	{
		int y=idx[i];
		if (y==fa || y==s[now]) continue;
		dfs2(y,now,y);	
	}
}
void pushup(int p)
{
	tr[p].ret=(tr[p*2].ret+tr[p*2+1].ret)%mod;
}
void pushdown(int p)
{
	tr[p*2].flag=(tr[p*2].flag+tr[p].flag)%mod;
	tr[p*2+1].flag=(tr[p*2+1].flag+tr[p].flag)%mod;
	tr[p*2].ret=(tr[p*2].ret+(tr[p*2].r-tr[p*2].l+1)*tr[p].flag%mod)%mod;
	tr[p*2+1].ret=(tr[p*2+1].ret+(tr[p*2+1].r-tr[p*2+1].l+1)*tr[p].flag%mod)%mod;
	tr[p].flag=0;
}
void bulid(int p,int l,int r)
{
	tr[p].l=l,tr[p].r=r;
	if (l==r)
	{
		tr[p].ret=a[l]%mod;
		return ;
	}
	int mid=(l+r)/2;
	bulid(p*2,l,mid),bulid(p*2+1,mid+1,r);
	pushup(p);
}
void update(int p,int x,int y,int z)
{
	if (x<=tr[p].l && tr[p].r<=y)
	{
		tr[p].ret=(tr[p].ret+(tr[p].r-tr[p].l+1)*z%mod)%mod;
		tr[p].flag=(tr[p].flag+z)%mod;
		return ; 
	}
	pushdown(p);
	int mid=(tr[p].l+tr[p].r)/2;
	if (x<=mid) update(p*2,x,y,z);
	if (mid<y) update(p*2+1,x,y,z);
	pushup(p);
}
long long query(int p,int x,int y)
{
	if (x<=tr[p].l && tr[p].r<=y) return tr[p].ret;
	pushdown(p);
	int mid=(tr[p].l+tr[p].r)/2;
	long long cnt=0;
	if (x<=mid) cnt=(cnt+query(p*2,x,y))%mod;
	if (mid<y) cnt=(cnt+query(p*2+1,x,y))%mod;
	return cnt;
} 
void trupdate(int x,int y,int z)
{
	z%=mod;
	while (f[x]!=f[y])
	{
		if (depth[f[x]]<depth[f[y]]) swap(x,y);
		update(1,id[f[x]],id[x],z);
		x=fat[f[x]];
	}
	if (depth[x]>depth[y]) swap(x,y);
	update(1,id[x],id[y],z);
}
long long trquery(int x,int y)
{
	long long cnt=0;
	while (f[x]!=f[y])
	{
		if (depth[f[x]]<depth[f[y]]) swap(x,y);
		cnt=(cnt+query(1,id[f[x]],id[x]))%mod;
		x=fat[f[x]];
	}
	if (depth[x]>depth[y]) swap(x,y);
	cnt=(cnt+query(1,id[x],id[y]))%mod;
	return cnt;
}
int cmp(qwq x,qwq y)
{
	return x.l<y.l;
}
int main() {
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m>>k;
	for (int i=2;i<=n;i++)
	{
		int x;
		cin>>x;
		add(x,i);
	}
	dfs1(1,0),dfs2(1,0,1),bulid(1,1,n);
	tot=0;
	for (int i=1;i<=m;i++)
	{
		int r,z;
		cin>>r>>z;
		e[++tot]={r,z,i};
	}
	for (int i=1;i<=n;i++)
	{
		b[i]=(qpow(depth[i],k)-qpow(depth[i]-1,k)+mod)%mod;
	}
	sort(e+1,e+m+1,cmp);
	int now=0;
	for (int i=1;i<=m;i++)
	{
		while (now<=e[i].l) trupdate(now,0,1),now++;
		ans[e[i].num]=trquery(e[i].q,0)*b[e[i].q]%mod;
//		cout<<e[i].l<<" "<<trquery(e[i].l,0)<<endl;
	}
	for (int i=1;i<=m;i++) cout<<ans[i]<<endl;
	return 0;
}