• LOJ6625 时间复杂度(min_25筛)


    本人在LOJ的第三题(前两题太水不好意思说了QwQ),欢迎大家踩std。

    题目链接:LOJ

    题目大意:定义函数 $f$:($minp$ 表示最小质因子)

    $$f(x)=egin{cases}0&x=1\x-2&xin prime\minp(x)-1&otherwiseend{cases}$$

    求 $f$ 前 $n$ 项的和对 $20190601$ 取模的值。

    $1le nle 10^{11}$。


    考虑 min_25 筛中的 $g_0(n,j)$($0$ 次方,即满足条件的数的个数)和 $g_0(n,j-1)$。

    $g_0(n,j)=sumlimits^n_{i=1}[iin prime || minp(i)>p_j]$

    $g_0(n,j-1)=sumlimits^n_{i=1}[iin prime || minp(i)ge p_j]$

    特别地,有 $g_0(n,0)=n-1$。

    所以 $g_0(n,j-1)-g_0(n,j)=sumlimits^n_{i=1}[i otin prime && minp(i)=p_j]$。

    也就是最小质因子为 $p_j$ 的数的个数。(不包括 $p_j$)

    那么答案为 $sumlimits^{|P|}_{j=1}p_j(g_0(n,j-1)-g_0(n,j)+1)-(n-1)-g_0(n,|P|)$。

    ……吗?

    由于 min_25 筛只能处理到 $le sqrt{n}$ 的质数,所以 $>sqrt{n}$ 的质数不会被统计到。

    所以分质数和合数两类讨论。合数部分上面讨论完了。质数部分是模板。

    答案为 $sumlimits^{|P|}_{j=1}p_j(g_0(n,j-1)-g_0(n,j))+g_1(n,|P|)-(n-1)-g_0(n,|P|)$。

    时间复杂度 $O(dfrac{n^{3/4}}{log n})$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=700070,mod=20190601;
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    ll n,w[maxn];
    int sq,tot,g1[maxn],g0[maxn],s1[maxn],pr[maxn],pl,id1[maxn],id2[maxn],g[maxn],ans,mn[maxn];
    bool vis[maxn];
    inline int add(int x,int y){return x+y<mod?x+y:x+y-mod;}
    inline int sub(int x,int y){return x<y?x-y+mod:x-y;}
    inline int id(ll x){return x<=sq?id1[x]:id2[n/x];}
    void init(){
        sq=sqrt(n);
        FOR(i,2,sq){
            if(!vis[i]) pr[++pl]=i,s1[pl]=(s1[pl-1]+i)%mod;
            FOR(j,1,pl){
                if(i*pr[j]>sq) break;
                vis[i*pr[j]]=true;
                mn[i*pr[j]]=pr[j];
                if(i%pr[j]==0) break;
            }
        }
        for(ll l=1,r;l<=n;l=r+1){
            r=n/(n/l);
            w[++tot]=n/l;
            if(n/l<=sq) id1[n/l]=tot;
            else id2[n/(n/l)]=tot;
            int t=w[tot]%mod;
            g0[tot]=sub(t,1);
            g1[tot]=(1ll*t*(t+1)/2-1)%mod;
        }
    }
    void calc_g(){
        FOR(i,1,pl) FOR(j,1,tot){
            if(1ll*pr[i]*pr[i]>w[j]) break;
            int pre=g0[j];
            g0[j]=sub(g0[j],sub(g0[id(w[j]/pr[i])],i-1));
            g1[j]=sub(g1[j],1ll*pr[i]*sub(g1[id(w[j]/pr[i])],s1[i-1])%mod);
            if(w[j]==n) g[i]=sub(pre,g0[j]);
        }
    }
    int main(){
        scanf("%lld",&n);
        init();
        calc_g();
        FOR(i,1,pl) ans=add(ans,1ll*pr[i]*g[i]%mod);
        ans=add(ans,sub(g1[id(n)],g0[id(n)]));
        ans=sub(ans,(n-1)%mod);
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    合唱队形2 洛谷U5874
    AC日记——石子归并 codevs 1048
    AC日记——舒适的路线 codevs 1001 (并查集+乱搞)
    AC日记——导弹拦截 洛谷 P1020 (dp+模拟)
    常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)
    AC日记——信息传递 洛谷 P2661 (tarjan求环)
    AC日记——逃出克隆岛 (bfs)
    数字对 (长乐一中模拟赛day2T2)
    改造二叉树 (长乐一中模拟赛day2T1)
    AC日记——热浪 codevs 1557 (最短路模板题)
  • 原文地址:https://www.cnblogs.com/1000Suns/p/10888832.html
Copyright © 2020-2023  润新知