P10812 【MX-S2-T3】跳 题解
题目分析
考虑 DP。
显然当没有
考虑从
我们从
接下来就是往回走。状态为
由于
注意到这是一个区间查询,可以使用树状数组查询,复杂度
for(int i=2;i<=n+1;i++)f[1][i]=1;
for(int x:son[1])
for(int j=2;j<=n+1;j++)
Add(x,f[1][j],j);
for(int i=2;i<=n;i++){
int bas=0;
for(int x:fa[i]){(bas+=f[x][i])%=p;}
(bas+=f[i-1][i])%=p;
for(int j=i+1;j<=n+1;j++){
(f[i][j]+=bas)%=p;
(f[i][j]+=(Query(j-1,i)-Query(i,i)+p)%p)%=p;
}
for(int x:son[i])
for(int j=i+1;j<=n+1;j++)
Add(x,f[i][j],j);
}
printf("%d\n",f[n][n+1]);
(其中
但是她 T 了,所以要优化复杂度。
观察查询的过程,发现我们完全不需要树状数组,因为移动
代码
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)
son[i].push_back(j),
fa[j].push_back(i);
for(int i=2;i<=n+1;i++)f[1][i]=1;
for(int x=2;x<=n;x++)
for(int j=2;j<=n+1;j++)s[x][j]=1;
for(int i=2;i<=n;i++){
long long bas=0;
for(int x:fa[i])bas+=f[x][i];
(bas+=f[i-1][i])%=p;
long long now=0;
for(int j=i+1;j<=n+1;j++){
f[i][j]+=bas+now;
now+=(s[j][i]%=p);
}
for(int j=i+1;j<=n+1;j++)f[i][j]%=p;
for(int x:son[i]){
for(int j=i+1;j<=n+1;j++)s[x][j]+=f[i][j];
}
}
printf("%d\n",f[n][n+1]);
本文作者:KIreteria
本文链接:https://www.cnblogs.com/11-twentythree/p/18330071
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步