1.8闲话

发布时间 2024-01-08 21:18:02作者: Vsinger_洛天依

听说天依入驻了X-Studio平台,你说的对但是X-Studio是啥没听过啊

推歌:一花依世界

  • \(\text{DZY love math}\)

简要题意:

定义 \(f(n)\)\(n\) 所含质因子的最大幂指数

\[\sum_{i=1}^n\sum_{j=1}^mf(\gcd(i,j)) \]

这啥题啊????

还是套路,先钦定 $ n<m $

\[\sum_{k=1}^{n}f(k)\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k] \]

\[\sum_{k=1}^{n}f(k)\sum_{i=1}^{\lfloor \frac nk\rfloor }\sum_{j=1}^{\lfloor \frac mk\rfloor }[\gcd(i,j)=1] \]

\[\sum_{k=1}^{n}f(k)\sum_{i=1}^{\lfloor \frac nk\rfloor }\sum_{j=1}^{\lfloor \frac mk\rfloor }\sum_{d|\gcd(i,j)}\mu(d) \]

\[\sum_{k=1}^{n}f(k)\sum_{d=1}^{n}\mu(d)\lfloor \frac n{kd}\rfloor\lfloor \frac m{kd}\rfloor \]

\[\sum_{t=1}^{n}\lfloor \frac n{t}\rfloor\lfloor \frac m{t}\rfloor\sum_{d|t}^{}\mu(d)f(\frac{t}{d}) \]

你说的对,但是明显这样就能解了

你说的对,但是我想学杜教筛了,正好在学莫反顺手学一下杜教筛试试用杜教筛A这题众所周知杜教筛复杂度是非常好的

对于数论函数 \(f\) ,杜教筛可以在低于线性时间的复杂度内计算
\(S(n)=\sum\limits_{i=1}^{n}f(i)\)

  • 算法思想

    照搬\(\text{OI-wiki}\)

    构造一个 \(S(n)\) 关于 \(S(\lfloor\frac{n}{i}\rfloor)\) 的递推式。

    数论函数 \(g\) 必满足:

    \[\begin{aligned} \sum_{i=1}^{n}(f * g)(i) & =\sum_{i=1}^{n}\sum_{d \mid i}g(d)f(\frac{i}{d}) \\ & =\sum_{i=1}^{n}g(i)S(\lfloor\frac{n}{i}\rfloor) \end{aligned} \]

    \(f*g\)不是 Dirichlet 卷积吗?没绷住

    可以得到

    \[\begin{aligned} g(1)S(n) & = \sum_{i=1}^n g(i)S(\lfloor\frac{n}{i}\rfloor) - \sum_{i=2}^n g(i)S(\lfloor\frac{n}{i}\rfloor) \\ & = \sum_{i=1}^n (f * g)(i) - \sum_{i=2}^n g(i)S(\lfloor\frac{n}{i}\rfloor) \end{aligned} \]

    可以构造恰当的数论函数 \(g\) 使

    • 快速计算
      \(\sum_{i=1}^n(f * g)(i)\)

    • 快速计算 \(g\) 的单点值,以用数论分块求解
      \(\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)\)

    则可以在较短时间内求得 \(g(1)S(n)\)

    你说得对,但是我没看懂怎么办???

    背板子呗,能咋办

    点击查看代码
    #include<bits/stdc++.h>
    using namespace std;
    namespace Fread{const int SIZE = (1 << 18);char buf[SIZE],*S,*T;inline char getchar() {if(S==T){T = (S = buf) + fread(buf,1,SIZE,stdin); if(S==T) return '\n';} return *S++;}}
    namespace Fwrite {const int SIZE = (1 << 18);char buf[SIZE],*S=buf,*T=buf+SIZE;inline void flush(){fwrite(buf,1,S-buf,stdout), S=buf;}inline void putchar(char c){*S++=c;if(S==T)flush();}struct NTR{ ~NTR() { flush(); }}ztr;}
    #ifdef ONLINE_JUDGE
    #define getchar Fread::getchar
    #define putchar Fwrite::putchar
    #endif
    namespace Fastio{
        struct Reader{
            template <typename T>
            Reader&operator>>(T&x){char c=getchar();bool f=false;while (c<'0'||c>'9') { if(c == '-')f = true;c=getchar();}x=0;while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}if(f)x=-x;return *this;}
            Reader&operator>>(double & x) {char c=getchar();short f=1,s=0;x=0;double t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar();if(c=='.')c=getchar();else return x*=f,*this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar();while(s--)t/=10.0;x=(x+t)*f;return*this;}
            Reader&operator>>(long double&x){char c=getchar();short f=1,s=0;x=0;long double t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar();if(c=='.')c=getchar();else return x*=f,*this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar();while(s--)t/=10.0;x=(x+t)*f;return*this;}
            Reader&operator>>(__float128&x){char c=getchar();short f=1,s=0;x=0;__float128 t=0;while((c<'0'||c>'9')&&c!='.'){if(c=='-')f*=-1;c=getchar();}while(c>='0'&&c<='9'&&c!='.')x=x*10+(c^48),c=getchar();if(c=='.') c = getchar();else return x*=f, *this;while(c>='0'&&c<='9')t=t*10+(c^48),s++,c=getchar();while(s--)t/=10.0;x=(x+t)*f;return *this;}
            Reader&operator>>(char&c){c=getchar();while(c=='\n'||c==' '||c=='\r')c=getchar();return *this;}
            Reader&operator>>(char*str){int len=0;char c=getchar();while(c=='\n'||c==' '||c=='\r')c=getchar();while(c!='\n'&&c!=' '&&c!='\r')str[len++]=c,c=getchar();str[len]='\0';return *this;}
            Reader&operator>>(string&str){char c=getchar();str.clear();while(c=='\n'||c==' '||c=='\r')c=getchar();while(c!='\n'&&c!=' '&&c!='\r')str.push_back(c),c=getchar();return *this;}
            template<class _Tp>
            Reader&operator>>(vector<_Tp>&vec){for(unsigned i=0;i<vec.size();i++)cin>>vec[i];return *this;}
            template<class _Tp,class _tp>
            Reader&operator>>(pair<_Tp,_tp>&a){cin>>a.first>>a.second;return *this;}
            Reader(){}
        }cin;
        const char endl='\n';
        struct Writer{
        static const int set_precision = 6;
        typedef int mxdouble;
            template<typename T>
            Writer&operator<<(T x){if(x==0)return putchar('0'),*this;if(x<0)putchar('-'),x=-x;static int sta[45];int top=0;while(x)sta[++top]=x%10,x/=10;while(top)putchar(sta[top]+'0'),--top;return*this;}
            Writer&operator<<(double x){if(x<0)putchar('-'),x=-x;mxdouble _=x;x-=(double)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar('0');while(top)putchar(sta[top]+'0'),--top;putchar('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar('0');while(top)putchar(sta[top]+'0'),--top;return*this;}
            Writer&operator<<(long double x){if(x<0)putchar('-'),x=-x;mxdouble _=x;x-=(long double)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar('0');while(top)putchar(sta[top]+'0'),--top;putchar('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar('0');while(top)putchar(sta[top]+'0'),--top;return*this;}
            Writer&operator<<(__float128 x){if(x<0)putchar('-'),x=-x;mxdouble _=x;x-=(__float128)_;static int sta[45];int top=0;while(_)sta[++top]=_%10,_/=10;if(!top)putchar('0');while(top)putchar(sta[top]+'0'),--top;putchar('.');for(int i=0;i<set_precision;i++)x*=10;_=x;while(_)sta[++top]=_%10,_/=10;for(int i=0;i<set_precision-top;i++)putchar('0');while(top)putchar(sta[top]+'0'),--top;return*this;}
            Writer&operator<<(char c){putchar(c);return*this;}
            Writer& operator<<(char*str){int cur=0;while(str[cur])putchar(str[cur++]);return *this;}
            Writer&operator<<(const char*str){int cur=0;while(str[cur])putchar(str[cur++]);return *this;}
            Writer&operator<<(string str){int st=0,ed=str.size();while(st<ed) putchar(str[st++]);return *this;}
            template<class _Tp>
            Writer&operator<<(vector<_Tp>vec){for(unsigned i=0;i<vec.size()-1;i++)cout<<vec[i]<<" ";cout<<vec[vec.size()-1];return *this;}
            template<class _Tp,class _tp>
            Writer&operator<<(pair<_Tp,_tp>a){cout<<a.first<<" "<<a.second;return *this;}
            Writer(){}
        }cout;
    }
    #define cin Fastio :: cin
    #define cout Fastio :: cout
    #define endl Fastio :: endl
    #define max(a,b) ((a) > (b) ? (a) : (b))
    #define min(a,b) ((a) < (b) ? (a) : (b))
    /* --------------- fast io --------------- */
    #define int long long
    using namespace std;
    const int maxn=2000010;
    int T,n,pri[maxn],cur,mu[maxn],Mu[maxn];
    bool vis[maxn];
    map<int,int> mapp;
    inline int S_mu(int x){
        if(x<maxn)  return Mu[x];
        if(mapp[x]) return mapp[x];
        int ret=1;
        for(int i=2,j;i<=x;i=j+1){
            j=x/(x/i);
            ret-=S_mu(x/i)*(j-i+1);
        }
        return mapp[x]=ret;
    }
    inline int S_phi(int x){
        int ret=0,j;
        for(int i=1;i<=x;i=j+1){
            j=x/(x/i);
            ret+=(S_mu(j)-S_mu(i-1))*(x/i)*(x/i);
        }
        return (ret-1)/2+1;
    }
    signed main() {
        cin>>T;
        mu[1]=1;
        for(int i=2;i<maxn;i++){
            if(!vis[i]){
                pri[++cur]=i;
                mu[i]=-1;
            }
            for(int j=1;j<=cur&&i*pri[j]<maxn;j++) {
                vis[i*pri[j]]=1;
                if(i%pri[j])
                    mu[i*pri[j]]=-mu[i];
                else {
                    mu[i*pri[j]]=0;
                    break;
                }
            }
        }
        for(int i=1;i<maxn;i++)
            Mu[i]=Mu[i-1]+mu[i];
        while(T--){
            cin>>n;
            cout<<S_phi(n)<<" "<<S_mu(n)<<endl;
        }
    }
    

    然后这个就能 A 掉洛谷上那个杜教筛模板

    这是非常好的模板

    然后代码还没打,等我彻底搞明白杜教筛再打咕咕咕


今日份的数论(?)基础知识

  • 单位元:

    单位函数 \(\varepsilon\)\(\text{Dirichlet}\) 卷积运算中的单位元,对于任何数论函数 \(f\) ,都有 \(f*\varepsilon=f\)

    \(\text{Dirichlet}\) 卷积运算中的单位元不是常函数,但在\(\text{Dirichlet}\)生成函数中等价于常数 \(1\)

    狄利克雷卷积运算中的数论函数常函数 \(1\) ,在狄利克雷生成函数中等价于黎曼函数 $\zeta $

    • \(\zeta\)是啥?

      \[\zeta(n)=\sum_{i=1}^{\infty}\frac 1{i^n}=\frac{1}{\Gamma(n)}\int^{\infty}_{0}\frac{x^{n-1}}{e^{x}}\text {dx} \]

      好吧我看不懂

  • 逆元:

    对于任何一个满足 \(f(x)\ne 0\) 的数论函数,如果有另一个数论函数 \(g(x)\) 满足 \(f*g=\varepsilon\) ,则称 \(g(x)\)\(f(x)\) 的逆元。由 等式的性质 可知,逆元是唯一的

    构造出 \(g(x)\) 的表达式为:

    \[g(x)=\dfrac {\varepsilon(x)-\sum\limits_{d\mid x,d\ne 1}{f(d)g\left(\dfrac {x}{d} \right)}}{f(1)} \]

  • 重要结论

    两个积性函数的 \(\text{Dirichlet}\) 卷积也是积性函数

    积性函数的逆元也是积性函数

    这也说明,数论函数的积性,在狄利克雷生成函数中的对应具有封闭性