[CF1139D]Steps to One

Preface

不会dp,所以反演(感谢@judgelight)。

Solution

考虑期望式子:

\[\begin{aligned} E(len)&=\sum_iP(len=i)\times i\\ &=\sum_iP(len=i)\sum_{j=1}^i1\\ &=\sum_i\sum_{j=1}^iP(len=i)\\ &=\sum_j\sum_{i\ge j}P(len=i)\\ &=\sum_jP(len\ge j)\\ &=1+\sum_jP(len>j)\\ &=1+\sum_j1-P(len\le j)\\ \end{aligned} \]

\(f_{i,j}\) 表示 \(len=i,gcd=j\) 的方案数,\(F_{i,j}\) 表示 \(len=i, j|gcd\) 的方案数。

则:

\[\begin{aligned} F_{i,j}&=\sum_{j|d}f_{i,d}=\lfloor\frac{m}{j}\rfloor^i\\ f_{i,j}&=\sum_{j|d}\mu(\frac{d}{j})F_{i,d}\\ f_{i,j}&=\sum_{j|d}\mu(\frac{d}{j})\lfloor\frac{m}{d}\rfloor^i\\ \end{aligned} \]

题目要求 \(gcd=1\),所以我们只关注 \(f_{i,1}\),则:

\[f_{i,1}=\sum_{d=1}^m\mu(d)\lfloor\frac{m}{d}\rfloor^i \]

根据定义,\(P(len\le j)=\frac{f_{j,1}}{m^j}\),为什么上面那一坨不是 \(\sum_{k=1}^{j} f_{k,1}\) 呢,因为如果长度在小于 \(j\)\(gcd\) 已经等于 \(1\) 了的话,无论怎样添加数,\(gcd\) 都恒为 \(1\)

让我们再看回期望式子:

\[\begin{aligned} E(len)&=1+\sum_j1-P(len\le j)\\ &=1+\sum_j1-\frac{f_{j,1}}{m^j}\\ &=1+\sum_j1-\frac{\sum_{d=1}^m\mu(d)\lfloor\frac{m}{d}\rfloor^j}{m^{j-1}}\\ &=1+\sum_j\frac{m^{j}-\sum_{d=1}^m\mu(d)\lfloor\frac{m}{d}\rfloor^{j}}{m^j}\\ &=1-\sum_j\sum_{d=2}^m\mu(d)\frac{\lfloor\frac{m}{d}\rfloor^j}{m^{j}}\\ &=1-\sum_{d=2}^m\mu(d)\sum_{j}\left(\frac{\lfloor\frac{m}{d}\rfloor}{m}\right)^j\\ \end{aligned} \]

现在 \(j\) 还无法处理,那我们处理一下。

发现:

\(S=x^1+x^2+x^3+\dots\)

\(xS=x^2+x^3+x^4+\dots\)

\((x-1)S=-x\)

\(S=\frac{x}{1-x}\)

知道了这个,\(j\) 自然就解决了:

\[\begin{aligned} E(len)&=1-\sum_{d=2}^m\mu(d)\sum_{j}\left(\frac{\lfloor\frac{m}{d}\rfloor}{m}\right)^j\\ &=1-\sum_{d=2}^m\mu(d)\frac{\frac{\lfloor\frac{m}{d}\rfloor}{m}}{1-\frac{\lfloor\frac{m}{d}\rfloor}{m}}\\ &=1-\sum_{d=2}^m\mu(d)\frac{\lfloor\frac{m}{d}\rfloor}{m-\lfloor\frac{m}{d}\rfloor}\\ \end{aligned} \]

Code

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5, mod = 1e9 + 7;

int m;
int primes[N], idx, miu[N], tmp;
bool st[N];

int ksm(int a, int b, int p) {
	int res = 1;
	while(b) {
		if(b & 1) res = (1ll * res * a) % p;
		a = (1ll * a * a) % p;
		b >>= 1;
	}
	return res;
} 
#define inv(x) ksm(x, mod - 2, mod)

void euler(int N){
	miu[1] = 1; N ++ ;
	for (int i = 2; i < N; ++ i ) {
		if(!st[i]) primes[ ++ idx] = i, miu[i] = -1;
		for (int j = 1, p = primes[1]; j <= idx && p * i < N; ++ j , p = primes[j]) {
			st[p * i] = 1;
			if(i % p == 0) {miu[p * i] = 0; break;}
			miu[p * i] = -miu[i];
		}
	}
}

int main(){
	cin >> m; 
	euler(m);
	for (int d = 2; d <= m; ++ d ) 
		tmp = ((tmp + 1ll * miu[d] * (m / d) * inv(m - m / d)) % mod + mod) % mod;
	cout << ((1 - tmp) % mod + mod) % mod;
	return 0;
}
posted @ 2023-06-15 22:18  cry_sky  阅读(5)  评论(1编辑  收藏  举报