LightOJ 1038

本文详细解析了lightOJ 1030题目,通过预处理和离线解决的方式,计算了一个数字到达1的期望次数。介绍了如何利用所有约数的递归关系来求解期望,并分享了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

lightOJ挂了好多天。。。搞得题解现在才写,不过那4道题一起过了还是挺开心的233.

http://lightoj.com/volume_showproblem.php?problem=1030

一个数字每次可以除以他的所有约数,问期望几次到1。

看见有T=20000,n=1e5,那么肯定就是预处理出来离线了。

f[i]表示到1的期望次数,那么f[i]就等于他的所有约数j的f[j]+1 之和。

设f[i]=t 则 t=(sigma(f[j]+1)+t+1)/cnt 其中j<i 且j | i ,cnt为j的个数+1,也就是约数总个数,就可以吧f[i]解出来了。

好像自从qt教了我这个解方程的方法后我做期望题都会想到解方程上,,,

#include<bits/stdc++.h>
#define maxl 100010
#define mod 1000000007
using namespace std;

int n,k,cas;
double f[maxl];

inline void init()
{
	f[1]=0;int len,cnt;
	double sum;
	for(int i=2;i<maxl;i++)
	{
		len=sqrt(i);cnt=0;sum=0;
		for(int j=1;j<=len;j++)
		if(i%j==0)
		{
			cnt++;sum+=f[j];
			if(j*j<i)
			{
				if(i/j!=i)
					sum+=f[i/j];
				cnt++;
			}
		}
		f[i]=(sum+cnt)/(cnt-1);
	}
}

int main()
{
	init();
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		scanf("%d",&n);
		printf("Case %d: %.6f\n",i,f[n]);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值