【期望dp 质因数分解】cf1139D. Steps to One
有一种组合方向的考虑有没有dalao肯高抬啊?
题目大意
有一个初始为空的数组$a$,按照以下的流程进行操作:
- 在$1\cdots m$中等概率选出一个数$x$并添加到$a$的末尾
- 如果$a$中所有元素的$\gcd=1$则完成这个数组$a$的修改
- 重复这一过程
求数组$a$的期望长度,$m \le 10^5,\mod 10^9+7$
题目分析
质因数分解的期望dp题
以下介绍的两个做法中,第一个做法本人不会所以 求助会做的dalao麻烦高抬一手 ;
第二个做法是对推得的dp式子质因数分解求解————当然网上更多的是莫比乌斯反演的做法,此处就不介绍了。
未完的做法一:组合考虑
考虑计算$f(d)$为:数组$a$的前$len-1$个(也即结束前的那一序列)$\gcd=d$时,对答案的期望长度贡献。
那么枚举结束前的长度$i$,记$h(d)$为$1\cdots m$中与$d$互质的数的个数;$g(i,d)$为一个$\gcd=d$的长度为$i$的序列的概率,有$f(d)=\sum\limits_{i=1}^{∞}(i+1)\times g(i,d)\times h(d)$。
当然,这样的式子远远不够。$h(d)$的计算非常轻松但是问题在于$g(i,d)$有没有什么组合上的表达方式。我最初以为$g(i,d)=\lfloor\frac{m}{d}\rfloor^{i-1}\times \frac{1}{m}$,意即将序列看做是无序取入的集合,确保$i-1$个元素都是$\{d,2d,3d\cdots\}$,并钦点一个$d$.但是这个处理有两个问题:1.序列不能够这样看成无序集合;2.并不是必须要有一个$d$才能使数组的$\gcd=d$,例如$\{2d,3d,5d\}$就有$\gcd=d$。
这个方向大概不太能行吧,为求出式子,$g(i,d)$可能还有更严苛的表达限制。
做法二:质因数分解
由于这里的长度是无穷的,所以处理角度还当是从序列的$\gcd$入手。
记$f_d$为当前数组已经$\gcd=d$,到达$\gcd=1$的状态的期望步数。(这个状态要比我上面那个状态要优秀得多)
容易得到转移 $f_d=1+\frac{1}{m} \sum\limits_{i=1}^mf_{\gcd(i,d)}$,
稍作化简得到 $f_d=1+\frac{1}{m} \sum\limits_{i\mid d,i\ne d}(f_i\times c(i,d)+\lfloor\frac{m}{d}\rfloor f_d)$,其中$c(i,d)=\sum\limits_{j=1}^m[\gcd (d,j)=i]$.
通过移项,有 $f_d=\frac{1+\frac{1}{m} \sum\limits_{i\mid d,i\ne d}f_i\times c(i,d)}{1-\frac{1}{m}\lfloor\frac{m}{d}\rfloor}$
那么对于这里$c(i,d)$的处理,就有很多方法了。这里介绍质因数分解的做法:
由于 $c(i,d)=\sum\limits_{j=1}^m[\gcd (d,j)=i]=\sum\limits_{j=1}^{\lfloor \frac{m}{i} \rfloor}[\gcd (\lfloor\frac{d}{i}\rfloor,j)=1]$,考虑子问题:$1\cdots c$中与$q$互质的数的个数。
那么将$q$唯一分解,有$q=p_1^{k_1}p_2^{k_2}\cdots$。注意到实际上我们只关心$p_i$而不关心$k_i$,所求的也就是$1\cdots c$中不存在任何$p_i$因数的数的个数。至此转为一个经典容斥问题,可以预处理出$r$个素因数再$2^r$容斥解决。
接下来是一些题外话,
上面提到的分解素因数的过程,理论上由于$10^5$内的数最多只有$6$个素因数,那么枚举每个素数检查是否为其因数的方法看上去也不算太差,
然而获得了1700ms+的“好”成绩:
一开始我还以为是$2^r$的dfs飞天了,然而后来意识到上述的这个素数分解的方法常数的确是巨大的……
可以这么看:对于一个要处理的数$x$,共约要遍历$\frac{x}{\ln x}$个素数。那么在这一部分上的总期望时间花费就大致是$\frac{m^2\sqrt m}{\ln m}$(好像这个上界太松没什么价值?)。
总之判断约数是否为质数的方法就要快很多:
#include<bits/stdc++.h>
#define MO 1000000007
typedef long long ll;
typedef std::vector<int> vec;
const int maxn = ; int n,num,cnt,pr[maxn],phi[maxn];
bool vis[maxn];
ll ans,f[maxn];
vec fac[maxn],opt; void makePrime()
{
phi[] = ;
for (int i=; i<maxn; i++)
{
if (!vis[i]) pr[++pr[]] = i, phi[i] = i-;
for (int j=,chk=; j<=pr[]&&i*pr[j]<maxn&&chk; j++)
if (pr[j]%i) phi[i*pr[j]] = phi[i]*(pr[j]-);
else chk = , phi[i*pr[j]] = phi[i]*pr[j];
}
for (int i=; i<maxn; i++)
for (int j=i; j<maxn; j+=i) fac[j].push_back(i);
}
int qmi(int a, int b)
{
int ret = ;
for (; b; b>>=,a=1ll*a*a%MO)
if (b&) ret = 1ll*ret*a%MO;
return ret;
}
void dfs(int x, int c, int t)
{
if (x==opt.size()) cnt += ((t&)?-num/c:num/c);
else{
dfs(x+, c, t);
dfs(x+, c*opt[x], t+);
}
} int calc(int p, int d)
{
vec().swap(opt), p /= d, num = n/d;
for (int pri; p>; )
{
pri = fac[p][];
if (vis[pri]) break;
opt.push_back(pri);
while (p%pri==) p /= pri;
}
cnt = , dfs(, , );
return cnt;
}
int main()
{
scanf("%d",&n), ans = , f[] = ;
makePrime();
for (int i=; i<=n; i++)
{
int lwr = (-1ll*qmi(n, MO-)*(n/i)%MO+MO)%MO;
for (int j=; j<fac[i].size()-; j++)
f[i] = (f[i]+1ll*f[fac[i][j]]*calc(i, fac[i][j])%MO)%MO;
f[i] = 1ll*(1ll*f[i]*qmi(n, MO-)%MO+)*qmi(lwr, MO-)%MO;
ans = (ans+f[i]+)%MO;
}
printf("%lld\n",1ll*ans*qmi(n, MO-)%MO);
return ;
}
END
【期望dp 质因数分解】cf1139D. Steps to One的更多相关文章
- CF 757E Bash Plays with Functions——积性函数+dp+质因数分解
题目:http://codeforces.com/contest/757/problem/E f0[n]=2^m,其中m是n的质因子个数(种类数).大概是一种质因数只能放在 d 或 n/d 两者之一. ...
- BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解
挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...
- CF1139D Steps to One(DP,莫比乌斯反演,质因数分解)
stm这是div2的D题……我要对不住我这个紫名了…… 题目链接:CF原网 洛谷 题目大意:有个一开始为空的序列.每次操作会往序列最后加一个 $1$ 到 $m$ 的随机整数.当整个序列的 $\gcd ...
- CF1139D Steps to One 题解【莫比乌斯反演】【枚举】【DP】
反演套 DP 的好题(不用反演貌似也能做 Description Vivek initially has an empty array \(a\) and some integer constant ...
- 【2019.7.22 NOIP模拟赛 T1】麦克斯韦妖(demon)(质因数分解+DP)
暴力\(DP\) 先考虑暴力\(DP\)该怎么写. 因为每个序列之后是否能加上新的节点只与其结尾有关,因此我们设\(f_i\)为以\(i\)为结尾的最长序列长度. 每次枚举一个前置状态,判断是否合法之 ...
- Codeforces 1139D(期望dp)
题意是模拟一个循环,一开始有一个空序列,之后每次循环: 1.从1到m中随机选出一个数字添加进去,每个数字被选的概率相同. 2.检查这个序列的gcd是否为1,如果为1则停止,若否则重复1操作直至gcd为 ...
- 题解-CF1139D Steps to One
题面 CF1139D Steps to One 一个数列,每次随机选一个 \([1,m]\) 之间的数加在数列末尾,数列中所有数的 \(\gcd=1\) 时停止,求期望长度 \(\bmod 10^9+ ...
- [学习笔记] Miller-Rabin质数测试 & Pollard-Rho质因数分解
目录 Miller-Rabin质数测试 & Pollard-Rho质因数分解 Miller-Rabin质数测试 一些依赖的定理 实现以及正确率 Pollard-Rho质因数分解 生日悖论与生日 ...
- 【bzoj1415】【聪聪和可可】期望dp(记忆化搜索)+最短路
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=57148470 Descrition 首先很明显是 ...
随机推荐
- Smaug Coverage
- 微信web开发者工具 && 微信调试页面
微信开发者工具 做微信公众号的过程中,自然避免不了登录账号然后进行调试,但是在chrome上我们没有办法登录,这是一个令人头疼的问题,比如这个公众号网页,只会提示出错,因为开发者限制了公众号网页的登录 ...
- 给用户添加sodu权限
vim /etc/sudoers 进入编辑模式,找到这一 行:"root ALL=(ALL) ALL"在起下面添加"xxx ALL=(ALL) ALL"(这里的 ...
- java 多线程 yield方法的意义
Thread.yield( )方法: 使当前线程从执行状态(运行状态)变为可执行态(就绪状态).cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一 ...
- 实例化php类的时候如何传参
当我们实例化一个php类的时候,要怎么传递参数呢?这取决于该类的构造方法. 例: person.class.php <?php class person{ var $name; var $col ...
- Spring Boot实战(2) Spring常用配置
1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...
- 警告: [SetContextPropertiesRule]{Context} Setting property 'source' to 'org.eclipse.jst.jee.server:esignmanage' did not find a matching property.解决
1.开发环境: 环境:myeclipse2015+tomcat7+win10 2.异常: 偶尔在部署项目的时候回发现tomcat7部署后配置文件按照路径居然找不到自己的项目.httP://localh ...
- DIV+CSS图片不间断滚动jquery特效(Marquee插件)及移动标签marquee整理
推荐一个jQuery的无缝文字滚动效果,同时也可以滚动图片,也叫做跑马灯效果. 此jquery插件,依托jquery库,能实现各种滚动效果,且让HTML代码符合W3C标准. marquee标签:创建一 ...
- 从零开始的全栈工程师——js篇(作用域 this 原型笔试题练习)
作用域 // 1. fn() function fn () { console.log(12) } var as = function () { console.log(45) } // 2. var ...
- Android基础Activity篇——Toast
1.Toast Toast在英文中有烤面包的意思,而在安卓开发中是用来提醒用户的消息显示.我猜这里之所以用Toast为该功能命名可能是因为消息的弹出方式就像面包烤好了从面包机中弹出来一样. 2.使用T ...