2021 天梯赛 L3-030 可怜的简单题

传送门

菜鸡的 lzx 比赛的时候式子画错了,错得一塌糊涂


【分析】

令 \(f_{d, l}\) 表示 \(\gcd A=d\) 且长度为 \(l\) 的概率

令 \(g_{d, l}\) 表示 \(\gcd A\mid d\) 且长度为 \(l\) 的概率

不难得到: \(\displaystyle g_{d, l}=\sum_{d\mid t}f_{t, l}={(n/d)^l\over n^l}\)

式中,\(n/d=\lfloor{n\over d}\rfloor\) 即向下取整

莫比乌斯反演得 \(\displaystyle f_{d, l}=\sum_{d\mid t}\boldsymbol \mu({t\over d})\cdot g_{t, l}\)

故考虑对长度期望的贡献:

贡献为恰好第一次达到 \(\gcd A=1\) 的概率,等价于长度为 \(l\) 且 \(\gcd A=1\) 的概率,扣去长度为 \((l-1)\) 且 \(\gcd A=1\) 的概率

故贡献为 \(f_{1, l}-f_{1, l-1}(f_{1, 0}=0)\)

计算总期望长度:

\(E(L)\)

\(=\displaystyle \sum_{l=1}^\infty l\cdot(f_{1, l}-f_{1, l-1})\)

\(=\displaystyle \sum_{l=1}^\infty l\cdot \sum_{1\mid t}\boldsymbol \mu({t\over 1})(g_{t, l}-g_{t, l-1})+\sum_{1\mid t}\boldsymbol \mu({t\over 1})\cdot g_{t, 0}\)

\(l=1\) 时 \(g_{t, 0}\) 被额外扣除了,需要重新加回

\(=\displaystyle \sum_{l=1}^\infty l\cdot \sum_{t=1}^n\boldsymbol \mu(t)[{(n/t)^l\over n^l}-{(n/t)^{l-1}\over n^{l-1}}]+\sum_{t=1}^n\boldsymbol \mu(t)\)

\(=\displaystyle \sum_{t=1}^n\boldsymbol \mu(t)\sum_{l=1}^{\infty}l\cdot [({n/t\over n})^l-({n/t\over n})^{l-1}]+\sum_{t=1}^n\boldsymbol \mu(t)\)

记 \(\displaystyle S(x)=\sum_{l=1}^\infty l\cdot (x^l-x^{l-1})\)

\(\displaystyle |x|<1\to S(x)=\sum_{l=1}^\infty l\cdot x^l-\sum_{l=1}^\infty (l+1)\cdot x^l-1=-\sum_{l=0}^\infty x^l={1\over x-1}\)

\(\displaystyle x=1\to S(x)=\sum_{l=1}^\infty l\cdot 0=0\)

\(\therefore E(L)\)

\(=\displaystyle \sum_{t=1}^n\boldsymbol \mu(t)\cdot S({n/t\over n})+\sum_{t=1}^n\boldsymbol \mu(t)\)

\(=\displaystyle \sum_{t=2}^n\boldsymbol \mu(t)\cdot S({n/t\over n})+\boldsymbol \mu(1)\cdot S({n/1\over n})+\sum_{t=1}^n\boldsymbol \mu(t)\)

\(=\displaystyle \sum_{t=2}^n\boldsymbol \mu(t) \cdot {1\over ({n/t\over n}-1)}+\sum_{t=1}^n\boldsymbol \mu(t)\)

\(=\displaystyle n\sum_{t=2}^n\boldsymbol \mu(t) \cdot {1\over (n/t-n)}+\sum_{t=1}^n\boldsymbol \mu(t)\)

对 \(n/t\) 进行整除分块,然后利用杜教筛,求出 \(\boldsymbol \mu(n)\) 的前缀和


杜教筛时,由 \(\boldsymbol \mu*\boldsymbol I=\boldsymbol \varepsilon\) 得到

\(\quad 1\)

\(\displaystyle =\sum_{i=1}^n\boldsymbol{\varepsilon}(i)\)

\(\displaystyle =\sum_{i=1}^n\sum_{d\mid i}\boldsymbol \mu({i\over d})\cdot \boldsymbol I(d)\)

\(\displaystyle =\sum_{d=1}^n\sum_{i=1}^{n/d}\boldsymbol\mu(i)\)

\(\displaystyle =\sum_{i=1}^n\boldsymbol \mu(i)+\sum_{d=2}^n\sum_{i=1}^{n/d}\boldsymbol \mu(i)\)

\(\therefore \displaystyle \sum_{i=1}^n\boldsymbol \mu(i)=1-\sum_{d=2}^n[\sum_{i=1}^{n/d}\boldsymbol \mu(i)]\)


【代码】

using namespace std;
typedef long long ll;
const int Lim=2.2e7, MAXN=Lim+10;
ll n, p;
inline ll fmul(ll a,ll x) { return (__int128)a*x%p; }
inline ll fpow(ll a,ll x) { ll ans=1; for(;x;x>>=1,a=fmul(a, a) ) if(x&1) ans=fmul(ans, a); return ans; }
inline ll inv(ll a) { return fpow(a, p-2); }

ll smu[MAXN];
int prime[MAXN],  cntprime;
bool nprime[MAXN];
unordered_map<ll, ll>  M;
inline ll summu(ll n){
    if(n<=Lim) return smu[n];
    if(M.count(n)) return M[n];
    for(ll r=n, l, d;r>=1; r=l-1){
        d=n/r;
        l=n/(d+1)+1;
        if(d<=Lim||M.count(d)) continue;
        ll tmp=1;
        for(ll ll=2, rr, dd;ll<=d;ll=rr+1){
            dd=d/ll;
            rr=d/dd;
            if(dd<=Lim) tmp-=fmul(rr-ll+1, smu[dd]);
            else tmp-=fmul(rr-ll+1, M[dd]);
        }
        M[d]=(tmp%p+p)%p;
    }
    return M[n];
}
inline void sieve(){
    smu[1]=1;
    for(int i=2;i<=Lim;++i){
        if(!nprime[i]) prime[++cntprime]=i, smu[i]=-1;
        for(int j=1;j<=cntprime;++j)
            if(i*prime[j]>Lim) break;
            else if(i%prime[j]){
                nprime[i*prime[j]]=1;
                smu[i*prime[j]]=-smu[i];
            }
            else{
                nprime[i*prime[j]]=1;
                smu[i*prime[j]]=0;
                break;
            }
    }
    for(int i=2;i<=Lim;++i){
        smu[i]+=smu[i-1];
        if(smu[i]>=p) smu[i]-=p;
        else if(smu[i]<0) smu[i]+=p;
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin>>n>>p;
    sieve();
    ll ans=0;
    summu(n);
    for(ll l=2, r, d, tmp=n%p;l<=n;l=r+1){
        d=n/l;
        r=n/d;
        ans+=fmul( summu(r)-summu(l-1) , inv(d-tmp+p) );
    }
    ans=(ans%p+p)%p;
    ans=( fmul(ans, n)+summu(n)+p )%p;
    cout<<ans;
    cout.flush();
    return 0;
}
上一篇:【030】纪妖–正版妖怪百科资料库


下一篇:Android利用广播监听设备安装和卸载应用程序