| 比赛 |
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;
}