Problem:

Codeforces 1139D

Analysis:

After ACing E, I gave up D and spent the left 30 minutes chatting with Little Dino.

Let \(f[n]\) be the expected number of steps needed to make the greatest common divisor (gcd) become \(1\) when the gcd is \(n\) now, and \(g(n,d)\) be the number of \(x(x\in[1,m])\) that \(gcd(x, n)=d\) . So we have:

\[f[n]=1+\sum_{d|n}\frac{f[d]\cdot g(n, d)}{m}
\]

To make it easy, multiply \(m\) to the equation:

\[mf[n]=m+\sum_{d|n}f[d]\cdot g(n, d)
\]

Notice that \(d\) can be \(n\), and \(g(n,n)\) is \(\lfloor\frac{m}{n}\rfloor\), so we have:

\[(m-\lfloor\frac{m}{n}\rfloor)f[n]=m+\sum_{d|n,d\neq n}f[d]\cdot g(n, d)
\]

Now the problem become how to calculate \(g(n,d)\). According to the defination,

\[\begin{aligned}
g(n, d)&=\sum_{i=1}^m[gcd(n, i)=d]\\
&=\sum_{i=1}^{\lfloor\frac{m}{d}\rfloor}[gcd(\frac{n}{d},i)=1]\\
&=\sum_{i=1}^{\lfloor\frac{m}{d}\rfloor}\epsilon\left(gcd(\frac{n}{d},i)\right)\\
\end{aligned}
\]

where \(\epsilon(x)=\begin{cases}1\ (x=1)\\0\ \mathrm{otherwise}\end{cases}\) .

According to the Mobius Theorem ( \(\mu * 1 = \epsilon\) ) :

\[\begin{aligned}
g(n,d)&=\sum_{i=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{t|\frac{n}{d},t|i}\mu(t)\\
&=\sum_{t|\frac{n}{d}}\mu(t)\cdot \lfloor \frac{m}{dt} \rfloor
\end{aligned}
\]

Let's return to \(f[n]\):

\[(m-\lfloor\frac{m}{n}\rfloor)f[n]=m+\sum_{d|n,d\neq n}f[d]\sum_{t|\frac{n}{d}}\mu(t)\cdot \lfloor \frac{m}{dt} \rfloor
\]

Preprocess the divisors of all integer \(x(x\in[1,m])\) and then calculate \(f[n]\) as the equation above directly. Because the number of divisors of most integers is very small ( for integers not more than \(100000\), the maximum is \(128\) and the total number is about \(10^6\) to \(2\times 10^6\)) , so it won't TLE.

At last, the answer is:

\[ans=1+\sum_{i=1}^{m}\frac{f[i]}{m}
\]

Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>
using namespace std; namespace zyt
{
typedef long long ll;
const int N = 1e5 + 10, p = 1e9 + 7;
vector<int> fac[N];
int n, f[N], pcnt, prime[N], mu[N];
bool mark[N];
void init()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j * j <= i; j++)
if (i % j == 0)
{
fac[i].push_back(j);
if (j * j != i)
fac[i].push_back(i / j);
}
mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!mark[i])
prime[pcnt++] = i, mu[i] = p - 1;
for (int j = 0; j < pcnt && (ll)i * prime[j] <= n; j++)
{
int k = i * prime[j];
mark[k] = true;
if (i % prime[j] == 0)
{
mu[k] = 0;
break;
}
else
mu[k] = p - mu[i];
}
}
}
int power(int a, int b)
{
int ans = 1;
while (b)
{
if (b & 1)
ans = (ll)ans * a % p;
a = (ll)a * a % p;
b >>= 1;
}
return ans;
}
int inv(const int a)
{
return power(a, p - 2);
}
int work()
{
scanf("%d", &n);
init();
f[1] = 0;
int ans = 0;
for (int i = 2; i <= n; i++)
{
for (int j = 0; j < fac[i].size(); j++)
{
int d = fac[i][j];
if (d == i)
continue;
int tmp = 0;
for (int k = 0, size = fac[i / d].size(); k < size; k++)
{
int t = fac[i / d][k];
tmp = (tmp + (ll)mu[t] * (n / d / t) % p) % p;
}
f[i] = (f[i] + (ll)tmp * f[d] % p) % p;
}
f[i] = (ll)(f[i] + n) * inv(n - n / i) % p;
}
for (int i = 1; i <= n; i++)
ans = (ans + f[i]) % p;
printf("%d", int(((ll)ans * inv(n) % p) + 1) % p);
return 0;
}
}
int main()
{
return zyt::work();
}

【Codeforces1139D_CF1139D】Steps to One (Mobius_DP)的更多相关文章

  1. 【CF1139D】Steps to One(动态规划)

    [CF1139D]Steps to One(动态规划) 题面 CF 你有一个数组,每次随机加入一个\([1,n]\)的数,当所有数\(gcd\)为\(1\)时停止,求数组长度的期望. 题解 设\(f[ ...

  2. 【贪心】codeforces D. Minimum number of steps

    http://codeforces.com/contest/805/problem/D [思路] 要使最后的字符串不出现ab字样,贪心的从后面开始更换ab为bba,并且字符串以"abbbb. ...

  3. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  4. 看懂SqlServer查询计划【转】

    原文链接:http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html 开始 SQL Server 查找记录的方法 SQL Server ...

  5. 【故障处理】ORA-28040: No matching authentication protocol

    [故障处理]ORA-28040: No matching authentication protocol 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者 ...

  6. 【ZZ】 移位贴图 Displacement Mapping

    http://blog.csdn.net/huazai434/article/details/5650629 说明:该技术需要VS3.0的支持!!! 一,移位贴图类似于地形渲染.不过由于移位纹理可以做 ...

  7. 【Android测试】【随笔】模拟双指点击

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5258660.html 手势 看到这个标题,很多人会想一想 ...

  8. 【转载】看懂SqlServer查询计划

    看懂SqlServer查询计划 阅读目录 开始 SQL Server 查找记录的方法 SQL Server Join 方式 更具体执行过程 索引统计信息:查询计划的选择依据 优化视图查询 推荐阅读-M ...

  9. 【工具】NS2安装记录

    献给同样为了NS2抓破了头皮的同志们. 1, Get Started: http://www.isi.edu/nsnam/ns/ns-build.html#allinone Build by piec ...

随机推荐

  1. iOS UIButton选中状态切换

    UIButton*payBtn = [UIButtonbuttonWithType:UIButtonTypeCustom]; payBtn.frame=CGRectMake(size.width-24 ...

  2. sanic官方文档解析之streaming(流动,滚动)和class_based_views(CBV的写法)

    1,streaming(流媒体) 1.1请求流媒体 Sanic允许你通过流媒体携带请求数据,如下,当请求结束await request.stream.read()就会返回None,仅仅只有post请求 ...

  3. 编译spark源码 Maven 、SBT 2种方式编译

    由于实际环境较为复杂,从Spark官方下载二进制安装包可能不具有相关功能或不支持指定的软件版本,这就需要我们根据实际情况编译Spark源代码,生成所需要的部署包. Spark可以通过Maven和SBT ...

  4. 如何解决Windows的端口占用问题?

    已知某应用在启动时会创建服务套接字,并将其绑定至端口8888,然而端口8888已被占用,如何解除占用? 以下为解决方案: 在cmd中运行netstat -ano|findstr 8888,其中的参数8 ...

  5. Vijos 1921 严厉的班长 【状态压缩动态规划】

    严厉的班长 描述 木姑娘在班级里面是班长.虽然是副班长,却有着比正班长更高的威信,并深受小朋友们的爱戴. 每天眼保健操时间,木姑娘都要监督所有小朋友认真做眼保健操.整个过程被描述为n个时间段,第i个时 ...

  6. IE67 下 setattribute class 失效

    解决办法.将class 换成 className ,同理.ff不能识别className,将其换成class element.setAttribute("class"," ...

  7. (linux)likely和unlikely函数

      在Linux内核中likely和unlikely函数有两种(只能两者选一)实现方式,它们的实现原理稍有不同,但作用是相同的,下面将结合linux-2.6.38.8版本的内核代码来进行讲解. 1.对 ...

  8. POJ 2421 Constructing Roads (Kruskal算法+压缩路径并查集 )

    Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19884   Accepted: 83 ...

  9. Silverlight中使用MVVM(3)

    Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...

  10. 官网下载java相关资源

    官网下载java相关资源 官网地址:http://www.oracle.com 一.下载JDK 1.首先进入Downloads >> Java For Developers,如图 2.点击 ...