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. requirement failed: Unacceptable value for property 'kafka.timeline.metrics.host_in_memory_aggregation', boolean values must be either 'true' or 'false

    requirement failed: Unacceptable value for property 'kafka.timeline.metrics.host_in_memory_aggregati ...

  2. v-cloak的用法和注意事项

    v-cloak是前端框架vue.js中的一个方法,作用是为了防止在页面加载时先出现变量名闪烁的情况,造成不好的用户体验, 例如:{{ v.name}} (闪一下)=> 张三 用法:html中:& ...

  3. AI - 深度学习之美十四章-概念摘要(1~7)

    原文链接:https://yq.aliyun.com/topic/111 本文是对原文内容中部分概念的摘取记录,可能有轻微改动,但不影响原文表达. 01 - 一入侯门"深"似海,深 ...

  4. 【Python语言】--Crontab结合Python脚本实现将日志每天写入到文件中

    一.前述 实际工作中将Python脚本每天定时写入到日志文件中的使用场景还是蛮多的,有很多种方法可以实现这种效果.本文选择一种方式实现,特将实现细节做如下分享,不当之处烦请指正. 二.具体 1.pyt ...

  5. 【朝花夕拾】Android性能篇之(八)ANR篇--草稿

    1.ANR概念 2.ANR发生场景 Android开发者官网 上说到了两个原因:(1)点击按键或者触摸屏幕等输入事件在5s内没有响应:(2)10s内没有完成广播事件.如下所示: Android wil ...

  6. Java中的基本类型转换,数据溢出原理

    java中的数据类型 java是一种强类型语言,在java中,数据类型主要有两大类,基本数据类型和引用数据类型,不同的数据类型有不同的数据存储方式和分配的内存大小. 基本数据类型中,各数据类型所表示的 ...

  7. 实体继承与@Builder注解共存

    在面向对象的设计里,继承是非常必要的,我们会把共有的属性和方法抽象到父类中,由它统一去实现,而在进行lombok时代之后,更多的打法是使用@Builder来进行对象赋值,我们直接在类上加@Builde ...

  8. 微信公众号开发C#系列-6、消息管理-普通消息接受处理

    1.概述 通过前面章节的学习,我们已经对微信的开发有了基本的掌握与熟悉,基本可以上手做复杂的应用了.本篇我们将详细讲解微信消息管理中普通消息的接收与处理.当普通微信用户向公众账号发消息时,微信服务器将 ...

  9. GoLang simple-project-demo-03

    变量的定义 package main import "fmt" func main() { var a = "initial" fmt.Println(a) v ...

  10. DS控件库 DS按钮多种样式

    在DS控件库(DSControls)中,DS按钮的功能非常多,通过设置不同的属性值来使按钮呈现不同的效果.DS按钮的常用属性如下: 使用不同的属性调出不同的外观样式示例