题解 sign
发现如果底数是固定的,那么转移是容易的
发现不同的底数只有根号种,所以好像可以
发现需要一个快速幂,所以实际上是
发现精细实现的话可以过
发现其实可以用光速幂优化到
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define pb push_back
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
int fa[N], a[N];
vector<int> to[N];
const ll mod=998244353;
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%mod,b>>=1) if (b&1) ans=ans*a%mod; return ans;}
// namespace force{
// ll f[N], ans[N], base, inv;
// void dfs(int u) {
// f[u]=1;
// for (auto v:to[u]) dfs(v), f[u]=f[u]*f[v]%mod;
// if (base==1) f[u]=f[u]*(a[u]+1)%mod;
// else f[u]=f[u]*(qpow(base, a[u]+1)-1)%mod*inv%mod;
// }
// void solve() {
// for (int i=1; i<=n; ++i) {
// // cout<<"i: "<<i<<endl;
// base=to[i].size();
// // cout<<"base: "<<base<<endl;
// inv=qpow(base-1, mod-2);
// dfs(1);
// ans[i]=f[i];
// // cout<<"f: "; for (int j=1; j<=n; ++j) cout<<f[j]<<' '; cout<<endl;
// }
// for (int i=1; i<=n; ++i) printf("%lld\n", (ans[i]%mod+mod)%mod);
// }
// }
// namespace task1{
// bool vis[N];
// int tem[N], sqr, tot;
// vector<int> buc[N], sta;
// ll f[N], ans[N], base, inv;
// void dfs(int u) {
// tem[++tot]=u;
// for (auto v:to[u]) dfs(v);
// }
// void solve() {
// sqr=sqrt(n);
// dfs(1);
// for (int i=1; i<=n; ++i)
// if (to[i].size()<=sqr) buc[to[i].size()].pb(i);
// else sta.pb(i);
// for (int i=0; i<=sqr; ++i) if (buc[i].size()) {
// base=i; inv=qpow(base-1, mod-2);
// for (auto it:buc[i]) vis[it]=1;
// int cnt=buc[i].size();
// for (int j=tot,u; j; --j) {
// u=tem[j];
// f[u]=1;
// for (auto& v:to[u]) f[u]=f[u]*f[v]%mod;
// if (base==1) f[u]=f[u]*(a[u]+1)%mod;
// else f[u]=f[u]*(qpow(base, a[u]+1)-1)%mod*inv%mod;
// if (vis[u]) {
// ans[u]=f[u];
// if (--cnt==0) break;
// }
// }
// for (auto it:buc[i]) vis[it]=0;
// }
// for (auto it:sta) {
// base=to[it].size(); inv=qpow(base-1, mod-2);
// for (int j=tot,u; j; --j) {
// u=tem[j];
// f[u]=1;
// for (auto& v:to[u]) f[u]=f[u]*f[v]%mod;
// if (base==1) f[u]=f[u]*(a[u]+1)%mod;
// else f[u]=f[u]*(qpow(base, a[u]+1)-1)%mod*inv%mod;
// if (u==it) {ans[u]=f[u]; break;}
// }
// }
// for (int i=1; i<=n; ++i) printf("%lld\n", (ans[i]%mod+mod)%mod);
// }
// }
namespace task2{
bool vis[N], npri[N];
int pri[N], pcnt;
int tem[N], sqr, tot;
vector<int> buc[N], sta;
ll f[N], ans[N], rec[325][N], base, inv;
void dfs(int u) {
tem[++tot]=u;
for (auto v:to[u]) dfs(v);
}
void solve() {
sqr=sqrt(n);
dfs(1);
// cout<<double(sizeof(rec))/1000/1000<<endl; exit(0);
for (int i=2; i<=sqr; ++i) {
if (!npri[i]) {
pri[++pcnt]=i;
for (int j=1; j<=n; ++j) rec[i][j]=qpow(i, a[j]+1);
}
for (int j=1,x; j<=pcnt&&i*pri[j]<=sqr; ++j) {
npri[x=i*pri[j]]=1;
for (int k=1; k<=n; ++k) rec[x][k]=rec[i][k]*rec[pri[j]][k]%mod;
if (!(i%pri[j])) break;
}
}
for (int i=1; i<=n; ++i)
if (to[i].size()<=sqr) buc[to[i].size()].pb(i);
else sta.pb(i);
for (int i=0; i<=sqr; ++i) if (buc[i].size()) {
base=i; inv=qpow(base-1, mod-2);
for (auto it:buc[i]) vis[it]=1;
int cnt=buc[i].size();
for (int j=tot,u; j; --j) {
u=tem[j];
f[u]=1;
for (auto& v:to[u]) f[u]=f[u]*f[v]%mod;
if (base==1) f[u]=f[u]*(a[u]+1)%mod;
else f[u]=f[u]*(rec[i][u]-1)%mod*inv%mod;
if (vis[u]) {
ans[u]=f[u];
if (--cnt==0) break;
}
}
for (auto it:buc[i]) vis[it]=0;
}
for (auto it:sta) {
base=to[it].size(); inv=qpow(base-1, mod-2);
for (int j=tot,u; j; --j) {
u=tem[j];
f[u]=1;
for (auto& v:to[u]) f[u]=f[u]*f[v]%mod;
if (base==1) f[u]=f[u]*(a[u]+1)%mod;
else f[u]=f[u]*(qpow(base, a[u]+1)-1)%mod*inv%mod;
if (u==it) {ans[u]=f[u]; break;}
}
}
for (int i=1; i<=n; ++i) printf("%lld\n", (ans[i]%mod+mod)%mod);
}
}
signed main()
{
freopen("sign.in", "r", stdin);
freopen("sign.out", "w", stdout);
n=read();
for (int i=2; i<=n; ++i) to[fa[i]=read()].pb(i);
for (int i=1; i<=n; ++i) a[i]=read();
// force::solve();
// task1::solve();
task2::solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2021-06-18 题解 星际旅行