ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-04-28 19:33:27  阅读:408  来源: 互联网

标签:over ll sum boldsymbol mu 2021 030 displaystyle L3


传送门

菜鸡的 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;
}

标签:over,ll,sum,boldsymbol,mu,2021,030,displaystyle,L3
来源: https://www.cnblogs.com/JustinRochester/p/14715478.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有