ICode9

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

习题:杜教筛(Sum)(杜教筛)

2021-01-31 15:34:35  阅读:151  来源: 互联网

标签:lfloor 2000005 frac int sum rfloor 杜教 习题 Sum


题目

传送门

思路

杜教筛的板子,拿来练手

pace1

\[\begin{aligned}ans&=\sum_{i=1}^{n}\phi(i)\\\end{aligned}\\g(n)=1,\phi(n)=f(n)\\h(n)=\sum_{d|n}\phi(d)*g(\frac{n}{d})=n\\ \]

\[h(n)=\sum_{d|n}f(d)g(\frac{n}{d})\\令F(n)=\sum_{i=1}^{n}f(i),H(n)=\sum_{i=1}^{n}h(i)\\\begin{aligned}H(n)&=\sum_{i=1}^{n}h(i)\\&=\sum_{i=1}^{n}\sum_{d|i}f(d)*g(\frac{i}{d})\\&=\sum_{i=1}^{n}\sum_{d|i}f(\frac{i}{d})g(d)\\&=\sum_{d=1}^{n}g(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\\&=\sum_{d=1}^{n}g(d)F(\lfloor\frac{n}{d}\rfloor)\\&=g(1)F(n)+\sum_{d=2}^{n}g(d)F(\lfloor\frac{n}{d}\rfloor)\end{aligned} \]

\[F(n)=\frac{H(n)-\sum_{d=2}^{n}g(d)F(\lfloor\frac{n}{d}\rfloor)}{g(1)} \]

其中\(H(n)\)的时间复杂度为\(O(1)\),\(g(d)\)也为\(O(1)\),对\(\sum_{d=2}^ng(d)F(\lfloor\frac{n}{d}\rfloor)\)数论分块就好了

时间复杂度\(O(n^{\frac{2}{3}})\)

pace2

\[ans=\sum_{i=1}^{n}\mu(i) \]

\[设f(i)=\mu(i),g(i)=1,那么显然h(i)=(f*g)(i)=[i=1]\\设F(i)=\sum_{i=1}^nf(i),H(i)=\sum_{i=1}^{n}h(i) \]

\[\begin{aligned}H(i)&=\sum_{i=1}^nh(i)\\&=\sum_{i=1}^n\sum_{d|i}f(\frac{i}{d})g(d)\\&=\sum_{d=1}^ng(d)F(\lfloor\frac{n}{d}\rfloor)\\&=g(1)F(n)+\sum_{d=2}^ng(d)F(\lfloor\frac{n}{d}\rfloor)\end{aligned} \]

\[F(n)=\frac{H(i)-\sum_{d=2}^ng(d)F(\lfloor\frac{n}{d}\rfloor)}{g(1)} \]

一样的,时间复杂度为$O(n^{\frac{2}{3}}) $

代码

#include<unordered_map>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int T;
int n;
int len;
int phi[2000005],mu[2000005];
int lenp,pri[2000005];
bool vis[2000005];
long long mphi[2000005];
long long mmu[2000005];
unordered_map<int,long long> m1;
unordered_map<int,long long> m2;
void prepa(int n)
{
    len=n;
    mphi[1]=1;
    mmu[1]=mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(vis[i]==0)
        {
            pri[++lenp]=i;
            phi[i]=i-1;mu[i]=-1;
        }
        for(int j=1;j<=lenp&&1ll*pri[j]*i<=n;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0)
            {
                mu[i*pri[j]]=0;
                phi[i*pri[j]]=pri[j]*phi[i];
                break;
            }
            mu[i*pri[j]]=mu[i]*mu[pri[j]];
            phi[i*pri[j]]=phi[i]*phi[pri[j]];
        }
        mmu[i]=mmu[i-1]+mu[i];
        mphi[i]=mphi[i-1]+phi[i];
    }
}
long long getphi(long long n)
{
    if(n<=len)
        return mphi[n];
    if(m1.count(n))
        return m1[n];
    long long temp=1ll*n*(n+1)/2;
    for(long long l=2,r;l<=n;l=r+1)
    {
        r=min(1ll*n/(n/l),1ll*n);
        temp=temp-1ll*(r-l+1)*getphi(n/l);
    }
    return m1[n]=temp;
}
long long getmu(int n)
{
    if(n<=len)
        return mmu[n];
    if(m2.count(n))
        return m2[n];
    long long temp=1;
    for(long long l=2,r;l<=n;l=r+1)
    {
        r=min(1ll*n/(n/l),1ll*n);
        temp=temp-1ll*(r-l+1)*getmu(n/l);
    }
    return m2[n]=temp;
}
void c_in()
{
    cin>>n;
    cout<<getphi(n)<<' '<<getmu(n)<<'\n';
}
int main()
{
    prepa(pow((1ll<<31)-1,2.0/3));
    cin>>T;
    for(int i=1;i<=T;i++)
        c_in();
    return 0;
}

标签:lfloor,2000005,frac,int,sum,rfloor,杜教,习题,Sum
来源: https://www.cnblogs.com/loney-s/p/14352704.html

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

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

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

ICode9版权所有