数论基础部分
改名!感觉还是把数学都写到这里吧。
数学菜批是这样的。
数论分块
算是前置芝士了,很多莫反题都要用这玩意。
假如现在我们有
甩个结论
首先令
例题 P3579 [POI2014] PAN-Solar Panels
好像是因为这个题才来写的这个笔记
不是很板,带一点思考量,我们首先能够发现,假如有一个
莫比乌斯反演
我总算是懂了,现在给一个莫比乌斯函数。
基于没有平方因子的性质,我们可以用欧拉筛求这东西,具体就是:
inline void GP(ll n){
vis[1]=1;mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
mu[i*prime[j]]=-mu[i];
}
}
fo(2,i,n) mu[i]+=mu[i-1];
}
莫比乌斯函数还有个性质:
也就是他等价于
啊啊啊,好多笔误。
考虑证明:
设
显然,由二项式定理:
所以当且仅当
有个小结论,这个还是很好理解的,
现在有了上面的结论,我们开始莫反的推导,假设现在有两个在非负数域上定义的函数
考虑证明,首先有:
这一步只是将式子变了一下,然后我们更换顺序:
然后由莫比乌斯函数的性质可以得知,当且仅当
得证。
其实莫反还有一种形式结论
到这里就差不多了,还有一些例题,之后会慢慢补上的。
P3455 [POI2007] ZAP-Queries
写出原答案式子:
把
直接莫反:
再改一下枚举顺序:
发现
筛一下
进一步考虑数论分块,现将
P2398 GCD SUM
双倍经验,还是上面那个式子,枚举一下
P1829 [国家集训队] Crash的数字表格 / JZPTAB
晚自习 40min 搞出来了,但是式子长的要死。
写出原式子
感觉这个分数形式很难搞,我们仍然采用枚举 gcd 的想法搞,这里跳了一步,直接把
把
之后把无关的
这样的话,我们可以处理
把后面记作
可是还有前面枚举
写出式子
P2257 YY的GCD
滚回来更新了,这题好像四个月前就在做题计划里了,一直没补(
好像有一个单测的简化版,简单写一下式子吧,我们默认令
然后莫反:
把
这样单次时间复杂度就是
令
这时候我们就发现后面的东西可以预处理了,在欧拉筛之后枚举一下倍数是
P3704 [SDOI2017] 数字表格
大力膜拜 lhc!!!
写出式子,默认
枚举
发现
之后正常莫反套路:
然后我们里面的
模仿上一题的优化套路,我们先令
我们设
因为
扩展欧几里得算法
求解不定方程,形似
洛谷的模板题是求
感觉 oi-wiki 的证法比较好理解,写一下:
我们设:
存在
要证明这俩方程是等价的,首先有
对于
推一下式子,有
那么就有
inline ll Exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) return x=1,y=0,a;
ll d=Exgcd(b,a%b,x,y);
ll t=x;x=y,y=t-(a/b)*y;return d;
}
卢卡斯定理
对于一个质数
有结论是
等我尽量补一下证明。
inline ll qpow(ll a,ll b){return (!b?1ll:qpow(a*a%p,b>>1)*((b&1ll)?a:1ll))%p;}
inline ll C(ll n,ll m){if(m>n) return 0;return pre[n]*qpow(pre[m],p-2)%p*qpow(pre[n-m],p-2)%p;}
inline ll Lucas(ll n,ll m){return (!m?1ll:C(n%p,m%p)*Lucas(n/p,m/p)%p);}
signed main(){
ll t;read(t);
while(t--)
{
read(n),read(m),read(p);
pre[0]=1;fo(1,i,max(n+m,p)) pre[i]=pre[i-1]*i%p;
wr(Lucas(n+m,n)),pr;
}
}
扩展欧拉定理
哦这个好久之前就写过博客了,写的好丑啊我靠。
欧拉函数
这里给出定义 :
我们记
展开是这样的:
欧拉筛显然可以把它筛出来:
inline void check_mul(ll n){
vis[1]=1,mul[1]=1;
fo(2,i,n)
{
if(!vis[i]) prime[++cnt]=i,f[i]=i,mul[i]=-1;
for(ll j=0;j<cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]] = 1;
f[i*prime[j]] = f[i] + 1;
if(i%prime[j]==0){
mul[i*prime[j]]=0;
break;
}
mul[i*prime[j]]=-mul[i];
}
}
}
对于单个欧拉函数的求法:
欧拉函数是特殊的积性函数,有性质
进一步,我们可以发现对于任意一个质数
因此,有
这样我们就可以在
欧拉定理
直接给出结论:
若
证明比较简单:
我们假定
具体证明可以参考 oiwiki。
拓展欧拉定理
对于欧拉定理,只有在
证明过程类似跳循环节,此处不再写。
那么,我们只需要预处理出
inline bool read(ll &opp,ll mod){ll x=0,t=1;char ch;ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-'){t=-1;}ch=getchar();}ll flag=0;while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);if(x>=mod) flag=1,x%=mod;ch=getchar();}opp=x*t;return flag;}
inline void wr(ll x){if(x<0){putchar('-');x=-x;}if(x>9){wr(x/10);}putchar(x%10+'0');}
inline ll qpow(ll a,ll b,ll mod){return (!b?1ll:qpow(a*a%mod,b>>1,mod)*((b&1)?a:1ll))%mod;}
ll a,m,b;
signed main(){
read(a),read(m);
ll k=m,phi=m;
fo(2,i,sqrt(m))
if(k%i==0)
{
phi=phi/i*(i-1);
while(k%i==0) k/=i;
}
if(k>1) phi=phi/k*(k-1);
ll op=read(b,phi);if(op) b+=phi;
wr(qpow(a,b,m)),pr;
}
中国剩余定理(CRT)
考虑我们现在有同余方程组:
对于这个方程组的求解,我们有结论:
令
则有
考虑证明,我们要证明
对于任意
于是就可以推到出,对于每一个
得证,CRT 的正确性就是需要
inline ll Exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) return x=1,y=0,a;
ll d=Exgcd(b,a%b,x,y);
ll t=x;x=y,y=t-(a/b)*y;return d;
}
signed main(){
read(n);fo(1,i,n) read(a[i]),read(b[i]),sum*=a[i];
fo(1,i,n)
{
ll opt=sum/a[i],x,y;
Exgcd(opt,a[i],x,y);
ans=(ans+b[i]*opt*x%sum)%sum;
}
wr((ans%sum+sum)%sum),pr;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?