我们考虑对于一个\(N\),他如果变成了他的约数\(x\),那又会变成一个子问题

我们定义\(F(n, k)\)为n操作k次的期望个数

那么我们有\(F(n, k) =\sum_{x|n} F(x, k - 1) * \frac{1}{d}\)(其中d为n的约数个数)

因为\(N\)的约数个数肯定在\(\sqrt N\)以内现在我们就有了一个\(O(\sqrt N K)\)的暴力了

前面的\(\sqrt N\)肯定是不能省略了,我们可不可以对\(K\)下手呢?

我们考虑\(N\)是质数,那么答案为\(\frac{N + 2^k - 1}{2^k}\)

再考虑一波\(N = p^x\)其中p是质数,那么我们考虑用上述\(DP求解\)

设$dp[i][j] \(为第i此操作后,为\)p^j$的概率

\(dp[i][j] = \sum_{l = 1}^x dp[i - 1][l] * \frac{1}{j}\)

最后的答案为\(\sum_{j = 1}^{x} dp[k][j] * p^j\)

我们发现每一个\(p_i^{j}\)互不影响,这又是一个积性函数

\(sum[i][j] * sum[i][k] = sum[i][j * k](gcd(j, k) == 1)\)

证明的话我们一样回归定义,假设变成\(p_1^j * p_2^0\)的概率为x,\(p_1^0 *p_2^k\)的概率为y,那么\(p_1^j*p_2^k\)的概率一定为\(x*y\)

于是我们只需要对\(N\)分解质因数后再套一个\(\prod\)即可

这样的复杂度是\(\sqrt N + K * log^3N=10^9\)

但是由于\(log\)不一定为2,所以这个复杂度是可以过这道题的

\(Code:\)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define int long long
#define D double
#define inf 123456789
#define mod 1000000007
il int read() {
re int x = 0, f = 1; re char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define drep(i, s, t) for(re int i = t; i >= s; -- i)
#define Next(i, u) for(re int i = head[u]; i; i = e[i].next)
#define mem(k, p) memset(k, p, sizeof(k))
#define lb(x) (x)&(-(x))
#define ls k * 2
#define rs k * 2 + 1
#define maxn 1000005
int n, m, prim[maxn], tot, dis[maxn], dp[maxn][20], ans, inv[100], Ans = 1;
il void get(int x) {
for(re int i = 2; i * i <= x; ++ i) {
if(x % i == 0) prim[++ tot] = i;
while(x % i == 0) x /= i, ++ dis[tot];
}
if(x != 1) prim[++ tot] = x, ++ dis[tot];
}
il int qpow(int a, int b) {
int r = 1;
while(b) {
if(b & 1) r = r * a % mod;
b >>= 1, a = a * a % mod;
}
return r;
}
signed main() {
n = read(), m = read();
get(n);
rep(i, 1, 60) inv[i] = qpow(i, mod - 2);
rep(T, 1, tot) {
mem(dp, 0), dp[0][dis[T]] = 1, ans = 0;
rep(i, 1, m) {
rep(j, 0, dis[T]) {
rep(k, j, dis[T]) dp[i][j] = (dp[i - 1][k] * inv[k + 1] + dp[i][j]) % mod;
}
}
rep(i, 0, dis[T]) ans = (ans + dp[m][i] * qpow(prim[T] % mod, i) % mod);
Ans = ans * Ans % mod;
}
printf("%lld", Ans);
return 0;
}

最新文章

  1. 结合Jexus + Kestrel 部署 asp.net core 生产环境
  2. 【BZOJ-4380】Myjnie 区间DP
  3. Device nodes and device stacks
  4. HttpClient简介 post get -转自ibm
  5. Redis应用
  6. Android Activity学习笔记(一)
  7. Part 64 to 66 Talking about Indexers in C#
  8. Android Drawable系列(1):自定义背景以及注意事项
  9. linux命令和awk
  10. 【译】1. Java反射——引言
  11. vim 高级编辑技巧
  12. Struts2中 Action class not found 问题
  13. FileZilla 客户端连接 FlieZilla 服务器 连接成功读取目录列表却失败的解决办法
  14. Windows NAT端口映射
  15. 2015-2016 Petrozavodsk Winter Training Camp, Nizhny Novgorod SU Contest (5/9)
  16. jquery的$.extend和$.fn.extend作用及区别,兼它们的一些小细节
  17. 设置 placeholder 字体颜色 : ::
  18. Day9 JSP
  19. Package ‘RSNNS’
  20. 经典DP 洛谷p1880 石子合并

热门文章

  1. go 学习笔记(4) package
  2. java第三次面试总结
  3. centos7 设置 查看 开机 启动项
  4. 操作系统systemctl命令
  5. 朴素贝叶斯算法源码分析及代码实战【python sklearn/spark ML】
  6. linux maven 安装与配置
  7. Linux下使用shell脚本自动备份和移动数据到大容量存储
  8. Android笔记(四十一) Android中的数据存储——SQLite(三)select
  9. c# 常见文件操作
  10. Python基础Day1—上