Problem   Codeforces #548 (Div2) - D.Steps to One

Time Limit: 2000 mSec

Problem Description

Input

The first and only line contains a single integer mm (1≤m≤100000,1≤m≤100000).

Output

Print a single integer — the expected length of the array aa written as P⋅Q^−1(mod10^9+7)

Sample Input

4

Sample Output

333333338

题解:概率dp做的太少了,不会做。。。

  首先是状态定义,dp[x]表示当前序列的gcd为x的情况下,还能添加数字个数的期望值,看了题解之后感觉这样很自然,但是自己想就想不到,有了这个定义之后状态转移就比较简单了,枚举下一个数字,根据期望的线性性质,有:

  

这样一来得到了一个O(n^2)的算法,显然不行,不过到这里的转化就很套路了,枚举gcd,式子化为:

  

f(y, x)指的是和x的gcd是y的数有多少个(从1到m),预处理出1~m的约数,复杂度mlogm,这样不用根号m枚举约数,枚举y这一步题解中给出的均摊复杂度是logm,(不会证qwq,不过很多地方都是这么分析的),这样一来就只剩下f的求解了,设x = y * a,则和x的gcd为b的数必定可表达为 p = y * b且gcd(a, b) = 1,这样一来就相当于计算从1到m/y中和a互质的数的个数,也就是和a没有相同的质因子,打打表(看题解)可以发现在题目的范围内b的质因子数至多为6,容斥一下即可计数,最终复杂度O(mlogm*2^6*6),是可以接受的。代码是看了题解的代码之后写的,主要学习这里质因数分解的操作。

 #include <bits/stdc++.h>

 using namespace std;

 #define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x)) const int maxn = + ;
const int maxm = + ;
const int maxs = + ; typedef long long LL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd; const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL mod = ;
const double eps = 1e-;
const double inf = 1e15;
const double pi = acos(-1.0); LL pow_mod(LL x, LL n, LL mod)
{
LL base = x % mod;
LL ans = ;
while (n)
{
if (n & )
{
ans = ans * base % mod;
}
base = base * base % mod;
n >>= ;
}
return ans % mod;
} LL m, invm;
unordered_map<int, int> prime[maxn];
vector<LL> fact[maxn];
bool is_prime[maxn];
LL dp[maxn]; void premanagement()
{
memset(is_prime, true, sizeof(is_prime));
is_prime[] = is_prime[] = false;
for (LL i = ; i < maxn; i++)
{
if (is_prime[i])
{
for (LL j = i; j < maxn; j += i)
{
LL cnt = ;
LL tmp = j;
while (tmp % i == )
{
cnt++;
tmp /= i;
}
prime[j][i] = cnt;
is_prime[j] = false;
}
is_prime[i] = true;
}
} for (LL i = ; i < maxn; i++)
{
for (LL j = * i; j < maxn; j += i)
{
fact[j].push_back(i);
}
}
} LL cal(LL x, LL n)
{
vector<LL> a;
LL curcnt = m / x;
for (auto &item : prime[n])
{
if (!prime[x].count(item.first))
{
a.push_back(item.first);
continue;
}
if (prime[x][item.first] == item.second)
{
continue;
}
else
{
a.push_back(item.first);
}
} LL sz = a.size();
LL lim = m / x;
for (LL sit = ; sit < (unit << sz); sit++)
{
LL tag = ;
LL val = ;
for (LL j = ; j < sz; j++)
{
if (sit & (unit << j))
{
val *= a[j];
tag *= -;
}
}
curcnt += tag * (lim / val);
}
return curcnt;
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
cin >> m;
invm = pow_mod(m, mod - , mod);
premanagement();
dp[] = ;
for (LL i = ; i <= m; i++)
{
LL &ans = dp[i];
ans = ;
for (LL item : fact[i])
{
ans += cal(item, i) * dp[item] % mod * invm % mod;
ans %= mod;
}
LL cnt = m / i;
ans = ans * m % mod * pow_mod(m - cnt, mod - , mod) % mod;
}
LL ans = ;
for (LL i = ; i <= m; i++)
{
ans = (ans + dp[i] * invm) % mod;
}
cout << ans << endl;
return ;
}

Codeforces #548 (Div2) - D.Steps to One(概率dp+数论)的更多相关文章

  1. Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题

    除非特别忙,我接下来会尽可能翻译我做的每道CF题的题面! Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题 题面 胡小兔和司公子都认为对方是垃圾. 为了决出谁才是垃 ...

  2. codeforces 768 D. Jon and Orbs(概率dp)

    题目链接:http://codeforces.com/contest/768/problem/D 题意:一共有k种球,要得到k种不同的球至少一个,q个提问每次提问给出一个数pi,问概率大小大于等于pi ...

  3. 2018.12.12 codeforces 935D. Fafa and Ancient Alphabet(概率dp)

    传送门 概率dp水题. 题意简述:给你数字表的大小和两个数列,数列中为0的数表示不确定,不为0的表示确定的,求第一个数列字典序比第二个数列大的概率. fif_ifi​表示第i ni~ ni n位第一个 ...

  4. Codeforces - 1139D - Steps to One (概率DP+莫比乌斯反演)

    蒟蒻数学渣呀,根本不会做. 解法是参考 https://blog.csdn.net/xs18952904/article/details/88785210 这位大佬的. 状态的设计和转移如上面博客一样 ...

  5. Codeforces Round #105 D. Bag of mice 概率dp

    http://codeforces.com/contest/148/problem/D 题目意思是龙和公主轮流从袋子里抽老鼠.袋子里有白老师 W 仅仅.黑老师 D 仅仅.公主先抽,第一个抽出白老鼠的胜 ...

  6. Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压

    题目链接: 题目 E. Another Sith Tournament time limit per test2.5 seconds memory limit per test256 megabyte ...

  7. CodeForces 54C-First Digit Law(数位,概率dp)

    题意: 给你n个区间,在每个区间里各取一个数(随机取),求这n个数中超过K%的数是首位为1数的概率 分析: dp[i][j]取前i个数,有j个是首位为1的数的概率 易知,dp[i][j]=dp[i-1 ...

  8. Codeforces 235B Let&#39;s Play Osu! 概率dp(水

    题目链接:点击打开链接 给定n表示有n个格子 以下每一个格子为O的概率是多少. 对于一段连续 x 个O的价值就是 x*x ; 问: 获得的价值的期望是多少. 思路: 把公式拆一下.. #include ...

  9. CodeForces 167B - Wizards and Huge Prize 期望概率dp

    初步分析:把赢了的巡回赛的a值加起来就是最后的剩余空间 这个明显的是状态转移的dp啊,然而他的状态比较骚是个数组,表示剩余空间,f(i,j,b),i表示比到第几场,j表示赢了几场,b就是里面的核心状态 ...

随机推荐

  1. echarts切换tab时,第一个图表显示,第二个图表不显示的解决办法

    首先这种情况,我在网上看到了好多人问,确实也有正解,但是只是说出了其错误出现的原因,并没有给出解决方法. 我也是深受其害,所以呢,在这里记录一下,分享给还在困扰着的你们,迅速找出解决办法. 首先,我先 ...

  2. 了解一下RabbitMQ

    RabbitMQ概述 RabbitMQ是遵从AMQP协议的 通信协议都设计到报文交互,换句话说RabbitMQ就是AMQP协议的Erlang的实现. AMQP说到底还是一个通信协议从low-level ...

  3. chrome谷歌浏览器开发者工具-网络带宽控制

    有时候我们想在本地测试一下图片预加载loading的加载情况,如下图: 可无奈一般网络带宽都比较好,基本上看不到效果,图片一下子就加载出来了, 可能这个时候有些小伙伴想到的办法是用定时器延迟加载 其实 ...

  4. SQL Server常用函数使用方法(学习)

    1.转载至 https://www.cnblogs.com/Brambling/p/6779434.html Substring()函数,用于截取字符串方法,三个参数 参数1:用于指定要操作的字符串 ...

  5. 老毛桃pe安装系统

    1.准备一个空白U盘,插入电脑. 2.下载老毛桃pe 3.下载完成后,打开老毛桃,默认制作成系统盘,傻瓜操作,无需修改参数 4.打开浏览器,下载要安装的系统 www.msdn.itellyou.cn ...

  6. c# 获取当前时间的微秒

    获取毫秒大家都经常用到. 大家应该都知道怎么用. 但是,毫秒下面还有微秒. 其实这个方法也已经在c#中. 只不过很少有人用到,所以查找资料也很少有人说. 下面代码就是获取微秒的方式: DateTime ...

  7. Java代码登录拦截器例子

    通常我们在点击某个按钮的时候,对某个对象进行操作,是需要登陆才能做的,这时候就需要一个拦截器对某个方法进行拦截, 比如你在一个图书管理中心中你要借书,这时候你就会被要求出示借书证,管理员才能借书给你. ...

  8. .net 配置swagger

    第一步: 在nuget.org中查找Swashbuckle并下载 在nuget.org中查找Swagger.net.UI,并下载 第二步: 下载完之后,App_Start多了三个文件 Swagger. ...

  9. C#工具:分词辅助类

    using System; using System.Collections; using System.IO; using System.Text.RegularExpressions; names ...

  10. 杭电ACM2018--母牛的故事

    母牛的故事 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...