D. Steps to One
题意
初始有一个空数组\(a\),接下来每次操作会这么做:
- 在\([1,n]\)中选择一个数,将其拼接在数组\(a\)后。
- 计算数组\(a\)的\(\gcd\)。
- 如果结果是\(1\),退出。
- 否则,回到步骤1.
试问数组\(a\)长度的期望,答案对\(1e^9+7\)取模。
题解
莫反解法
考虑dp。
设\(dp[x]\)为当前数组的\(\gcd\)为\(x\)时的期望长度,那么答案便是
\]
由\(dp[x]\)的意义,考虑对其因子进行转移,即
\]
然而\(O(n^2)\)的时间复杂度必定是超时的,于是考虑优化。
对于\(\gcd(i,x)\),它必定是\(x\)的因子,于是可以优化成
\]
其中\(h(x,d)\)表示\([1,n]\)中与\(x\)的\(\gcd\)为\(d\)的个数,即
\]
对于优化后的\(dp[x]\)的表达式,由于左右两边可能都含有\(dp[x]\),于是我们把\(dp[x]\)单独分离出来
\]
其中
\]
通过移项,变形得
\]
接下来再分析\(h(x,d)\):
\]
变换求和顺序得
\]
带入原式
\]
AC代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(NULL)
#define sc(z) scanf("%d", &(z))
#define _ff(i, a, b) for (ll i = a; i <= b; ++i)
#define _rr(i, a, b) for (ll i = b; i >= a; --i)
#define _f(i, a, b) for (ll i = a; i < b; ++i)
#define _r(i, a, b) for (ll i = b - 1; i >= a; --i)
#define pii pair<int, int>
#define mkp make_pair
#define endl "\n"
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
const ll mod = 1e9 + 7;
ll dp[N];
vector<ll> mind[N];
bool prime[N];
ll primes[N], cnt, mu[N], inv[N];
void precompute() {
mu[1] = 1, cnt = 0;
_ff(i, 2, N) {
if (!prime[i]) {
primes[cnt++] = i;
mu[i] = -1;
}
_f(j, 0, cnt) {
if (primes[j] * i > N) break;
prime[i * primes[j]] = 1;
if (i % primes[j]) {
mu[i * primes[j]] = -mu[i];
} else {
mu[i * primes[j]] = 0;
break;
}
}
}
_ff(i, 1, N) {
mu[i] = (mu[i] + mod) % mod;
for (int j = i + i; j < N; j += i) mind[j].push_back(i);
}
inv[1] = 1;
_ff(i, 2, N) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
int main() {
ll n; cin >> n;
precompute();
_ff(x, 2, n) {
dp[x] = n;
for (ll d : mind[x]) {
//由于之前筛因子的时候并没有把自身筛进去,于是这里要单独计算t=x/d的情况
ll s = n / x * mu[x / d] % mod;
for (ll t : mind[x / d]) {
s = (s + n / d / t * mu[t]) % mod;
}
dp[x] = (dp[x] + s * dp[d]) % mod;
}
dp[x] = dp[x] * inv[n - n / x] % mod;
}
ll ans = 0;
_ff(i, 1, n) ans = (ans + dp[i]) % mod;
ans = ans * inv[n] % mod;
cout << ans + 1 % mod;
return 0;
}
无穷级数解法
根据期望的定义,我们可以得到
\]
如何计算\(P(i)\)呢?我们设\(P(E)\)为事件\(E\)发生的概率,设当前长度为\(len\),那么我们可以计算\(len\)的期望\(P(len>x)\):
\]
注意到\(len>x\)就意味着所有前\(x\)个数是不互质的,那么\(P(len>x)\)就可以表示为
\]
我们令\(ans_i=\sum_{x=1}^{\infty}P(\gcd(a_1,a_2,...,a_x)=i)\),那么最终答案就为
\]
那么如何计算\(ans_i\)呢?我们可以根据容斥原理,先计算前\(x\)个数都是x的倍数的概率,再减去前\(x\)个数的\(\gcd\)是\(i\)的倍数的概率,即
\]
我们很容易知道,在\([1,n]\)中取一个\(i\)的倍数的概率为\(\frac{\lfloor \frac{n}{i}\rfloor}{n}\),那么原式就为
\]
很容易知道,级数\(\sum_{x=1}^{\infty}(\frac{\lfloor \frac{n}{i}\rfloor}{n})^x\)是收敛的,收敛为\(\frac{1}{1-\frac{\lfloor \frac{n}{i}\rfloor}{n}}-1\)。
AC代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(NULL)
#define sc(z) scanf("%d", &(z))
#define _ff(i, a, b) for (int i = a; i <= b; ++i)
#define _rr(i, a, b) for (int i = b; i >= a; --i)
#define _f(i, a, b) for (int i = a; i < b; ++i)
#define _r(i, a, b) for (int i = b - 1; i >= a; --i)
#define pii pair<int, int>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
const ll mod = 1e9 + 7;
ll ans[N];
ll qpow(ll a, ll b) {
ll res = 1;
while (b) {
if (b & 1) res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res;
}
ll inv(ll x) { return qpow(x, mod - 2); }
int main() {
ll n; cin >> n;
ll dans = 1;
_rr(i, 2, n) {
ans[i] = (inv((1 - n / i * inv(n) + mod) % mod) - 1 + mod) % mod;
for (ll j = i + i; j <= n; j += i) {
ans[i] = (ans[i] - ans[j] + mod) % mod;
}
dans = (dans + ans[i]) % mod;
}
cout << dans;
return 0;
}
D. Steps to One的更多相关文章
- animation-timing-function: steps() 详解
在应用 CSS3 渐变/动画时,有个控制时间的属性 <animation-timing-function> .它的取值中除了常用到的 贝萨尔曲线以外,还有个让人比较困惑的 steps() ...
- CSS3 Animation 帧动画 steps()
@keyframes fn{ 0%{} 100%{} } CSS3的Animation有八个属性 animation-name :动画名 fn animation-duration:时间 1s ani ...
- SAML 2.0 setup steps, 效果图
Steps of setting up SAML SSO. 效果图 # Registry a Identity Provider services in:(Might need purchase) I ...
- 【译】css动画里的steps()用法详解
原文地址:http://designmodo.com/steps-c... 原文作者:Joni Trythall 我想你在css 动画里使用steps()会和我一样有很多困惑.一开始我不清楚怎样使用它 ...
- css3动画中的steps值详解
css3的动画的animation-timing-function属性定义了动画的速度曲线,一般的速度曲线大家都知道,什么ease,linear,ease-in,ease-out,还有自定义贝塞尔曲线 ...
- steps animation
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- sdutoj 2623 The number of steps
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2623 The number of steps ...
- SAP NWBC for HTML and Desktop configuration steps[From sdn]
Summary :- This dcoumnenst conatin the information about requirement , hardware , configuration step ...
- 【转载】7 Steps for Calculating the Largest Lyapunov Exponent of Continuous Systems
原文地址:http://sprott.physics.wisc.edu/chaos/lyapexp.htm The usual test for chaos is calculation of the ...
- BSGS算法_Baby steps giant steps算法(无扩展)详解
Baby Steps-Varsity Giant Step-Astronauts(May'n・椎名慶治) 阅读时可以听听这两首歌,加深对这个算法的理解.(Baby steps少女时代翻唱过,这个原唱反 ...
随机推荐
- 用python从网页下载单词库
从网站下载单词库 1 每一页有几百个单词 2 每一个单词有独立的URL,URL中包含单词的中文解释 3 使用的库 requests,pyquery,web #coding:utf-8 import r ...
- BLP(Bell–LaPadula模型)(MAC)
Bell-LaPadula模型侧重于数据的保密性和对机密信息的受控访问 基于状态机,该状态机在一个计算机系统中具有一组允许的状态,并且从一个状态到另一种状态的转换由状态转移函数定义. 该模型定义了一个 ...
- ChatGPT检测器开发者在知乎的文章,记录一下
我们开发了第一款中英双语ChatGPT检测器,还有... - 蝈蝈的文章 - 知乎 https://zhuanlan.zhihu.com/p/598395917
- 使用Apache PDFBox实现拆分、合并PDF
目录 使用Apache PDFBox实现拆分.合并PDF 问题背景 Apache PDFBox介绍 拆分PDF 合并PDF 拆分 + 合并 完整代码 参考: 使用Apache PDFBox实现拆分.合 ...
- 剑指 Offer 栈与队列
09. 用两个栈实现队列 没啥意思 不要想复杂了 就是暴力 class CQueue { public: CQueue() { } /* 一个主栈 一个缓存栈 来回导 得到队头 copy后一端变空了 ...
- Outlook配置文件位置
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles ...
- 给自己提个醒,渲染模版引擎handlebars已经足够好用了,不要再到处乱看浪费时间了。
<html><body onload="renderHello()"><div id="target">Loading... ...
- 【git】3.2git分支-分支的新建与合并
资料来源 (1) https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0% ...
- 物理机安装mysql8, 修改数据库目录
自动安装mysql ,并修改数据库目录. #! /bin/bash #mysql官方下载路径:https://dev.mysql.com/downloads/mysql/ # 配置dnf源 mkdir ...
- ICPC2020 沈阳
F-Kobolds and Catacombs 牛客网 题意:对于\(n(n<=10^6)\)个数的序列,划分区间,每个区间内部从小到大排序,要求最后整个序列单调不下降,求最多可以划分为多少个区 ...