1.8闲话
听说天依入驻了X-Studio平台,你说的对但是X-Studio是啥没听过啊
推歌:一花依世界
- \(\text{DZY love math}\)
简要题意:
定义 \(f(n)\) 为 \(n\) 所含质因子的最大幂指数
这啥题啊????
还是套路,先钦定 $ n<m $
你说的对,但是明显这样就能解了
你说的对,但是我想学杜教筛了,正好在学莫反顺手学一下杜教筛试试用杜教筛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}\) 卷积也是积性函数
积性函数的逆元也是积性函数
这也说明,数论函数的积性,在狄利克雷生成函数中的对应具有封闭性