uva11762(期望)

来源:互联网 发布:轴承型号大全软件 编辑:程序博客网 时间:2024/04/29 23:28

题意:

给出一个n,随机选一个比n小的素数i,如果i能被n整除;n/=i;否则n=n;

问n除到1的期望次数;


思路:

先打素数表;

然后

f[n] = 1/p f[a0] + 1/p f[a1].....+ 1其中p是小于n的素数个数,ai表示,如果这个素数能被n整除,ai = n/这个素数,否则ai = n;

然后用这个公式递推就行了;


#include <cstdio>#include <cstring>#include <cmath>const int N = 1000005;int vis[N], num[N], prime[N], n;double f[N];void init() {int k = 0;memset(vis, 0, sizeof(vis));memset(prime, 0, sizeof(prime));memset(num, 0, sizeof(num));for(int i = 2; i < N; i++) {num[i] = num[i - 1];if(!vis[i]) {num[i]++;prime[k++] = i;vis[i] = 1;for(int j = 2; i * j < N; j++) {vis[i * j] = 1;}}}}double dfs(int x) {if(vis[x])return f[x];vis[x] = 1;    int s = 0;double p = 1.0 / num[x];double sum = 0;for(int i = 0; i < num[x]; i++) {if(x % prime[i] == 0) {sum += dfs(x / prime[i]);s++;} }return f[x] = (sum + num[x]) / s;}int main(){init();memset(vis, 0, sizeof(vis));vis[1] = 1, f[1] = 0;int t;int cas = 1;scanf("%d", &t);while(t--) {scanf("%d", &n);printf("Case %d: %.10lf\n",cas++, dfs(n));}return 0;}


0 0