qbxt五一数学Day2
1. 判断素数(素性测试)
1. 试除
bool isprime(int n)
{
if (n<2) return false;
for (int i=2;i*i<=n;i++)
if (!(n%i)) return false;
return true;
}
2. Miller-Rabin 素性测试
Theorm 1
若 是素数,则对于任意 ,设 ,则
中至少有一个成立 .
随便找若干个数 进行判定,很大概率对(4~8 个在 long long
范围稳了)(取质数效果较好)
时间复杂度
const int PrimeList[]={2,3,5,11,37,43,67,73,97}; // for Miller-Rabin
ll qmul(ll a,ll n,ll P)
{
ll ans=0; if (!n) return 0;
while (n)
{
if (n&1) ans=(ans+a)%P;
n>>=1; a=(a+a)%P;
} return ans%P;
}
ll qpow(ll a,ll n,ll P)
{
ll ans=1;
while (n)
{
if (n&1) ans=qmul(ans,a,P)%P;
n>>=1; a=qmul(a,a,P)%P;
} return ans;
}
bool miller_rabin(ll n,int a)
{
ll d=n-1,r=0;
while (!(d&1)){++r; d>>=1;}
ll x=qpow(a,d,n);
if (x==1) return true;
for (int i=0;i<r;i++)
{
if (x==n-1) return true;
x=qmul(x,x,n)%n;
} return false;
}
bool MillerRabin(ll n)
{
if (n<2) return false;
for (int i=0;i<9;i++)
{
if (n==PrimeList[i]) return true;
if (n%PrimeList[i]==0) return false;
if (!miller_rabin(n,PrimeList[i])) return false;
} return true;
}
* 欧拉函数
定义:
定义为 中与 互质的数的个数,即:
Theorm *
欧拉函数的求值公式:
Proof:容斥原理
公式求 值:
ll phi(ll n) // O(sqrt(n))
{
ll ans=n;
for (int i=2;i*i<=n;i++)
if (!(n%i))
{
ans=ans/i*(i-1);
while (!(n%i)) n/=i;
}
if (n>1) ans=ans/n*(n-1);
return ans;
}
Theorm *(欧拉函数是积性函数)
若 互质,则 .
Proof:由求值式子显然得证 .
2. 逆元
定义:
若 使得 ,则 成为 模 意义下的逆元,记作 .
Theorm 2
逆元存在的充要条件是 .
我们知道费马小定理和欧拉定理:
Theorm 3(费马小定理)
对于 且 为质数,有:
Theorm 4(欧拉定理)
对于 ,有:
其中 是欧拉函数 .
素数求逆元:用费马小定理,答案是 .
其他:
- 用欧拉定理,答案是 .
- 用 exgcd,问题等价于求解 .
求 的逆元:
预处理阶乘,阶乘逆元可以
求, 的逆元可以
求 .
3. exgcd(扩展欧几里得)
求解不定方程
其中 是整数 .
Theorm 5(裴蜀定理 / 贝祖定理)
有解当且仅当 .
所以只需要处理 的解即可 .
注意到 ,设 .
我们按照欧几里德算法(即辗转相除法),当 时,容易发现 .
若不然,如果我们知道
的解,我们就可以依照如下方法求 的解:
int ex_gcd(int a,int b,int& x,int& y)
{
if (!b){x=1; y=0; return a;}
int xp,yp,g=ex_gcd(b,a%b,xp,yp);
x=yp; y=xp-yp*(a/b); return g;
return 0;
}
4. 离散对数(BSGS 算法求解)
BSGS:大步小步算法北上广深·百事公司·阿姆斯特朗算法
求解同余方程
其中 是质数 .
由费马小定理,这个 不会超过 .
分成如下数表:
如图,将所有行转换到第一行,用一个 set
或 hash
维护即可 .
ll BSGS(ll a,ll b,ll p) // a^x=b (mod p)
{
int s=sqrt(p),x=1; set<int> se;
for (int i=0;i<s;i++){se.insert(x); x=1ll*x*a%p;}
int y=qpow(qpow(a,s,p),p-2,p),z=b;
for (int i=1;;i++)
{
if (se.count(z))
{
z=qpow(a,(i-1)*s,p);
for (int j=(i-1)*s;;j++)
if (z==b) return j;
else z=1ll*z*a%p;
} z=1ll*z*y%p;
}
} // 要判无解只需要判断循环次数是否过多即可 .
5. CRT(中国剩余定理)
考虑合并两个方程,
法一:大数翻倍法(zhx 的神仙解法)
枚举 判断是否成立
static pair<ll,ll> MergeEqu(ll a1,ll m1,ll a2,ll m2)
{
if (m2>m1) swap(m1,m2),swap(a1,a2);
while (a1%m2!=a2) a1+=m1;
return make_pair(a1,lcm(m1,m2));
}
法二:用扩展欧几里得解
令 ,则
则:
用扩欧解出 即可 .
6. 线性筛(xxs)
1. 筛素数
碍事筛埃氏筛:
notprime[1]=true;
for (int i=2;i<=n;i++)
{
if (notprime[i]) continue;
for (int j=i+i;j<=n;j++) notprime[j]=true;
}
这是对于每个素数 枚举它的所有倍数筛掉
我们反过来,用每个数 枚举它的所有素数倍:
vector<int> plist; notprime[1]=true;
for (int i=2;i<=n;i++)
{
if (!notprime[i]) plist.push_back(i);
for (auto x:plist)
{
int now=i*x;
if (now>n) break;
notprime[x]=true;
}
} // C++11
/* 数组写法 */
notprime[1]=true;
for (int i=2;i<=n;i++)
{
if (!notprime[i]) plist[++pcnt]=i;
for (int j=1;j<=pcnt;j++)
{
int now=i*plist[j];
if (now>n) break;
notprime[plist[j]]=true;
}
}
注意到每个数可能被筛多次,例如:
翻过来后就是枚举到 时,找到 筛掉 .
我们希望每个数只被它的最小质因子筛掉 .
我们进行模拟:
当我们发现 时,枚举:
- 素数 :筛掉 .
- 素数 :注意到 (上一个素数)是 的倍数,所以后面的素数都不用枚举了,因为不是最小素因子(此处最小素因子至多是 )
用这种想法写出最终代码:
vector<int> plist; notprime[1]=true;
for (int i=2;i<=n;i++)
{
if (!notprime[i]) plist.push_back(i);
for (auto x:plist)
{
int now=i*x;
if (now>n) break;
notprime[x]=true;
if (!(i%x)) break;
}
}
2. 筛积性函数(,)
当 是素数时:
当第 行成立,显然 .
因为没有其他增加的素因子,由欧拉函数计算式得 .
如果互素(即第 行成立),由积性显然有 ,
在板子上改一改就行辣
notprime[1]=true; phi[1]=mu[1]=1;
for (int i=2;i<=n;i++)
{
if (!notprime[i]){plist.push_back(i); phi[i]=i-1; mu[i]=-1;}
for (auto x:plist)
{
int now=i*x;
if (now>n) break;
notprime[now]=true;
if (!(i%x)){phi[now]=phi[i]*x; mu[now]=0; break;}
else{phi[now]=phi[i]*phi[x]; mu[now]=mu[i]*mu[x];}
}
}
7. 数论函数与狄利克雷卷积
1.
1. 定义与性质
:莫比乌斯函数 ,数论容斥函数 .
定义:
对于整数 ,定义:
Theorm:对于 ,有 ( 是积性函数 .
Proof:
设
其中 (即 互质).
当 时(其余情况易证),
2. 例题
问在 到 中有多少个数可以表示为
其中 .
数据范围:
对于对于一个 ,存在 个 满足条件(显然有 ,即 ).
注意到有数会重复,e.g.
答案即为:
(这个 是为了去掉 )
暴力求即可 .
2. 狄利克雷卷积
1. 定义
数论卷积(或狄利克雷(Dirichlet)卷积):
对于数论函数 ,定义他们的狄利克雷卷积为:
注: 是枚举因子 .
有性质:
- 交换律: .
- 结合律:
- 分配律:
2. 特殊函数的狄利克雷卷积
一
其中 .
即对于 ,有:
二
其中 .
即:
三
Proof:
3. 例题
求和变形技巧:
- 增加枚举变量
- 交换枚举顺序
- 删除无用变量
Problem 1
给定 ,求:
(第三个等号是把 转换成枚举倍数).
然后预处理 ,时间复杂度 .
Problem 2
给定 ,问存在多少 ,使得 互质 .
显然题目让求的是:
和上一题几乎一样 [表情]
3. 莫比乌斯反演
即
Proof:
8. 计数
1. 计数原理
1. 加法原理
一件事若干类(并列),方案数加起来
2. 乘法原理
一件事若干步(递进),方案数乘起来
2. 排列组合
定义
组合: 中无序选 :
排列: 中有序选 :
性质
组合意义:选不选的
组合意义:第一件选不选
反复用前面那个式子
组合意义:选两次
组合意义:取数用乘法原理、组合数两种算法
组合意义:建立奇数项与偶数项的一一对应,以达成消去的效果(第一项取反) .
qwq
(二项式定理)
组合意义:多项式乘法选数 .
几道小题
Problem 1
里选 数,数字可以相同,求方案数.
一个独特的解法:设选 .
构造 ,然后对 作组合,得答案为
Problem 2
里选 数,数字不能相邻,求方案数.
类似的设选 .
构造 ,然后对 作组合,得答案为
Problem 3
计算
第二个等号用组合意义:
以下是博客签名,正文无关
本文来自博客园,作者:yspm,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/14726141.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】