『正睿OI 2019SC Day7』
<更新提示>
<第一次更新>
<正文>
简单数论
质因子分解
素性测试
素性测试指的是对一个正整数是否为质数的判定,一般来说,素性测试有两种算法:
\(1.\) 试除法,直接尝试枚举因子,时间复杂度\(O(\sqrt n)\)。
\(2.\) \(Miller-Rabin\)算法,利用费马小定理和二次探测定理对素数进行测试,有小概率误判,时间复杂度\(O(log_2n)\)。
\(Code:\)
inline bool judge(long long x,long long p)
{
if ( x % p == 0 || quickpow( p%x , x-1 , x ) != 1 ) return false;
register long long k = x-1 , val;
while ( ( k & 1 ) == 0 )
{
val = quickpow( p%x , k>>=1 , x );
if ( val != 1 && val != x-1 ) return false;
if ( val == x-1 ) return true;
}
return true;
}
inline bool MillerRabin(long long x)
{
if ( x == 2 ) return true;
if ( x < 2 || ( x & 1 ) == 0 ) return false;
for (int i=0;i<10;i++)
{
if ( x == P[i] ) return true;
if ( !judge( x , P[i] ) ) return false;
}
return true;
}
质因子分解
质因子分解则指的是对一个正整数按照算术基本定理的形式进行分解,也有两种常用算法:
\(1.\) 试除法,直接尝试枚举因子,时间复杂度\(O(\sqrt n)\)。
\(2.\) \(Pollard's\ Rho\)算法,配合\(Miller-Rabin\)算法对整数进行随机化分解,期望时间复杂度\(O(\sqrt [4]{n}log_2n)\)。
\(Code:\)
inline long long Euclid(long long a,long long b) { return b == 0 ? a : Euclid(b,a%b); }
inline long long Random(void) { return ( 0LL + rand() ) << 30 | rand(); }
inline void PollardsRho(long long n)
{
if ( n == 1 ) return;
if ( MillerRabin( n ) ) { ans = max( ans , n ); return; }
long long x = Random() % n , c = Random() % n , y = x;
for (int i=2,k=2;true;i++)
{
register long long val = Euclid( n + y - x , n );
if ( val > 1 && val < n )
return PollardsRho(val) , PollardsRho(n/val);
if ( i == k ) k <<= 1 , y = x;
x = ( quickmul( x , x , n ) + c ) % n;
if ( x == y ) break;
}
return PollardsRho( n );
}
数论算法
欧几里得算法
利用辗转相除法求两个数的最大公约数,时间复杂度\(O(log_2n)\)。
\(Code:\)
inline int Euclid(int a,int b) { return b == 0 ? a : Euclid(b,a%b); }
扩展欧几里得算法
利用欧几里得算法求不定方程的特解,时间复杂度\(O(log_2n)\)。
\(Code:\)
inline int Extended_Euclid(int a,int &x,int b,int &y,int c)
{
if ( b == 0 ) { x = c/a , y = 0; return a; }
else
{
int p = Extended_Euclid(b,x,a%b,y,c);
int x_ = x , y_ = y;
x = y_ , y = x_ - a / b * y_;
return p;
}
}
类欧几里得算法
利用整除拆分技巧计算整除求和式,时间复杂度\(O(log_2n)\)。
\(Code:\)
inline long long f(long long a,long long b,long long c,long long n)
{
if ( a == 0 ) return ( n + 1 ) * ( b / c ) % Mod;
if ( a >= c || b >= c )
return ( f( a%c , b%c , c , n ) + n * ( n + 1 ) % Mod * INV2 % Mod * ( a / c ) % Mod + ( n + 1 ) * ( b / c ) % Mod ) % Mod;
long long val = ( a * n + b ) / c;
return ( ( n * val % Mod - f( c , c - b - 1 , a , val-1 ) ) % Mod + Mod ) % Mod;
}
中国剩余定理
利用公式计算线性同余方程组的特解,要求模数互质,时间复杂度\(O(nlog_2n)\)。
\(Code:\)
inline void CRT(void)
{
m_ = 1;
for (int i=1;i<=n;i++)
m_ *= m[i];
for (int i=1;i<=n;i++)
M[i] = m_ / m[i];
for (int i=1;i<=n;i++)
{
long long y;
Exeuclid(M[i],t[i],m[i],y,1);
ans += a[i]%m_ * M[i]%m_ * t[i]%m_;
ans %= m_;
}
}
拓展中国剩余定理
利用扩展欧几里得算法每次求一个同余方程的解,然后依次合并,从而求得线性同余方程组的解,不要求模数互质,时间复杂度\(O(nlog_2n)\)。
\(Code:\)
inline long long ExCRT(void)
{
long long m_ = m[1] , x = r[1];
for (int i=2;i<=n;i++)
{
long long x_,y_;
if ( ( r[i] - x ) % Euclid( m_ , m[i] ) ) return -1;
long long p = Exeuclid( m_ , x_ , m[i] , y_ , r[i] - x );
long long Mod = m[i] / p;
//要对当前的解先取模,防止爆longlong
x_ = ( x_ % Mod + Mod ) % Mod;
x += x_ * m_;
m_ = m_ * m[i] / p;
x = ( x + m_ ) % m_;
}
return x;
}
BSGS算法
利用分块思想求解离散对数问题的解,要求模数与底数互质,时间复杂度\(O(\sqrt n)\)。
\(Code:\)
inline long long Baby_Step_Giant_Step(long long a,long long b,long long p)
{
map < long long , long long > hash; hash.clear();
long long t = (long long)sqrt(p) + 1 , mul = 1;
b %= p;
for (int j=0;j<t;j++)
{
hash[ mul * b % p ] = j;
mul = mul * a % p;
}
if ( a % p == 0 ) return b == 0 ? 1 : -1;
a = 1;
for (int i=0;i<=t;i++)
{
long long j = ( hash.find(a) != hash.end() ? hash[a] : -1 );
if ( j >= 0 && i * t - j >= 0 ) return i * t - j;
a = a * mul % p;
}
return -1;
}
ExBSGS算法
利用同余性质缩小模数规模,直至模数与底数互质,使用\(BSGS\)算法求解离散对数,时间复杂度\(O(\sqrt n)\)。
\(Code:\)
inline long long ExBSGS(long long a,long long b,long long p)
{
if ( b == 1 ) return 0;
long long cnt = 0 , d , k = 1;
while ( ( d = Euclid(a,p) ) ^ 1 )
{
if ( b % d ) return -1;
b /= d , p /= d , ++cnt;
k = k * ( a / d ) % p;
if ( k == b ) return cnt;
}
unordered_map < long long , long long > Hash; Hash.clear();
long long t = (long long)sqrt(p) + 1 , mul = 1;
for (int j=0;j<t;j++)
{
Hash[ mul * b % p ] = j;
mul = mul * a % p;
}
for (int i=0;i<=t;i++)
{
long long j = ( Hash.find(k) != Hash.end() ? Hash[k] : -1 );
if ( j >= 0 && i * t - j + cnt >= 0 ) return i * t - j + cnt;
k = k * mul % p;
}
return -1;
}
原根
分解模数可以判定原根的存在性,同时可以根据欧拉定理求解原根。
\(Code:\)
pending further supplement
二次剩余
如果存在原根,则可以利用\(BSGS\)算法计算二次剩余,时间复杂度\(O(\sqrt n)\)。
\(Code:\)
pending further supplement
\(Tonelli–Shanks\)算法可以在\(O(log^2n)\)的时间内计算二次剩余。
\(Code:\)
pending further supplement
\(Cipolla\)算法可以在\(O(log_2n)\)的时间内计算二次剩余。
\(Code:\)
pending further supplement
数论函数
定义和概念
数论函数:定义域为正整数集,陪域为复数域的函数。
积性函数:对于任意\(a,b\in N^+,gcd(a,b)=1\),有\(f(ab)=f(a)f(b)\)的数论函数\(f\)被称为积性函数。
完全积性函数:对于任意\(a,b\in N^+\),有\(f(ab)=f(a)f(b)\)的数论函数\(f\)被称为完全积性函数。
积性函数的性质
\(1.\) 设\(n=\prod p_i^{a_i}\),则有\(f(n)=\prod f(p_i^{a_i})\)。
\(2.\) 若数论函数\(f,g\)均为积性函数,则\(f*g,f/g\)也均为积性函数。
狄利克雷卷积
对于数论函数\(f,g\),我们定义\(f\)和\(g\)的\(dirichlet\)卷积为:
\]
狄利克雷卷积的性质
\(1.\) 交换律:\(f\times g=g\times f\)。
\(2.\) 结合律:\((f\times g)\times h=f\times (g\times h)\)。
\(3.\) 分配律:\(f\times (g+h)=f\times g+ f\times h\)。
\(4.\) 单位元:\(f\times \epsilon=f\)。
\(5.\) 积性性:若函数\(f,g\)是积性函数,则\(f\times g\)也是积性函数。
莫比乌斯反演
莫比乌斯定理:若\(g=f\times I\),则\(f=g\times \mu\)。
证明:
\]
底和顶
\(1.\) \(x\geq n⇔\lfloor x\rfloor\geq n\)。
\(2.\) \(x> n⇔\lceil x\rceil> n\)。
\(3.\) \(x\leq n⇔\lceil x\rceil\leq n\)。
\(4.\) \(x< n⇔\lfloor x\rfloor< n\)。
\(5.\) 对于\(i\in[1,n]\),\(\lfloor \frac{n}{i} \rfloor,\lceil \frac{n}{i} \rceil\)都只有\(O(\sqrt n)\)种不同的取值。
杜教筛
对于计算数论函数\(f\)的前缀和,如果我们能够找到合适的函数\(g\),并能快速计算函数\(g\)和函数\(f\times g\)的前缀和,那么我们就可以快速计算函数\(f\)的前缀和。
公式:
\]
另一种形式,设\(S(n)=\sum_{i=1}^nf(i)\),那么有:
\]
可以用整除分块和记忆化搜索来计算,当我们线性筛预处理前\(n^{\frac{2}{3}}\)个前缀和时,杜教筛的时间复杂度为\(O(n^{\frac{2}{3}})\)。
\(Code:\)
inline pll BishopSieve(int n)
{
if ( n <= m ) return make_pair( phi[n] , mu[n] );
if ( sum.count( n ) ) return sum[n];
long long res1 = 1LL * n * ( n + 1 ) / 2 , res2 = 1;
for (int l=2,r;l<=n;l=r+1)
{
r = n/l ? min( n/(n/l) , n ) : n;
pll val = BishopSieve( n/l );
res1 -= 1LL * ( r - l + 1 ) * val.first;
res2 -= 1LL * ( r - l + 1 ) * val.second;
}
return sum[n] = make_pair( res1 , res2 );
// 求欧拉函数和莫比乌斯函数的前缀和
}
总结
感觉其实数论算法还有不少没有学,并且最大的问题就是做的题不够多,很多经典的套路还不够熟练,尤其是数论函数这一块。再就是代码不够熟练,还需要多刷题。
<后记>
『正睿OI 2019SC Day7』的更多相关文章
- 『正睿OI 2019SC Day8-Day17』
于是就迎来\(10\)天的自闭考试了,每天写点小总结吧. Day8 第一天就很自闭啊,考题分别是数学题+建模题+图论. 前两道题都没有什么算法,但是难度还是有的,于是就做不太出来,特别是第一题.第二题 ...
- 『正睿OI 2019SC Day5』
网络流 网络流的定义 一个流网络\(G=(V,E)\)为一张满足以下条件的有向图: 每一条边有一个非负容量,即对于任意\(E\)中的\((u,v)\) , 有\(c(u,v)\geq0\). 如果\( ...
- 『正睿OI 2019SC Day4』
总结 今天是一场欢乐的\(ACM\)比赛,于是我队得到了全场倒数的好排名. 好吧,其实还是怪自己不能怪队友啦.对于\(ACM\),可能最主要的还是经验不足,导致比赛的时候有点紧张.虽然队友为了磕一道题 ...
- 『正睿OI 2019SC Day1』
概率与期望 总结 老师上午几乎是在讲数学课,没有讲什么和\(OI\)有关的题目,所以我就做了一点笔记. 到了下午,老师讲完了有关知识点和经典模型,就开始讲例题了.前两道例题是以前就做过的,所以没有什么 ...
- 『正睿OI 2019SC Day6』
动态规划 \(dp\)早就已经是经常用到的算法了,于是老师上课主要都在讲题.今天讲的主要是三类\(dp\):树形\(dp\),计数\(dp\),\(dp\)套\(dp\).其中计数\(dp\)是我很不 ...
- 『正睿OI 2019SC Day3』
容斥原理 容斥原理指的是一种排重,补漏的计算思想,形式化的来说,我们有如下公式: \[\left | \bigcup_{i=1}^nS_i \right |=\sum_{i}|S_i|-\sum_{i ...
- 『正睿OI 2019SC Day2』
分治 普通分治 普通分治是指针对序列或平面问题的分治算法. 思想 普通分治的思想是指将一个序列问题或平面问题通过某种划分方式划分为若干个子问题,直到子问题规模足够小,可以直接回答,再通过合并得到原问题 ...
- 10.23 正睿停课训练 Day7
目录 2018.10.23 正睿停课训练 Day7 A 矩形(组合) B 翻转(思路) C 求和(思路 三元环计数) 考试代码 B1 B2 C 2018.10.23 正睿停课训练 Day7 期望得分: ...
- 正睿OI DAY3 杂题选讲
正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...
随机推荐
- Cocos Creator 返回字符串长度(字符),汉字计数为2
function strLength(str) { var a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) ...
- Linux自有服务(1)-Linux从入门到精通第五天(非原创)
文章大纲 一.运行模式二.用户与用户组管理(重点)三.网络设置四.ssh服务(重点)五.学习资料下载六.参考文章 自有服务,即不需要用户独立去安装的软件的服务,而是当系统安装好之后就可以直接使用的 ...
- IDEA控制台输出中文乱码问题
IntelliJ IDEA 真的是一款很方便的Java开发工具,但是关于中文乱码这个问题我不得不吐槽,这个编码也弄得这么麻烦干嘛,真想找idea开发者干架,我敢打包票我能在一分钟之内一拳飞过去让他跪下 ...
- spring学习2
使用注解配置spring 步骤: 1. 导包4(core/bean/context/spel)+1(logging)+spring-aop包(新版spring需要导入这个包) 2. 为主配置文件引入新 ...
- requirements 操作
requirements作用描述: 很多 Python 项目中经常会包含一个 requirements.txt 文件,里面内容是项目的依赖包及其对应版本号的信息列表, 即项目依赖关系清单,其作用是用来 ...
- SWA2G422&485JK2G基础篇: 硬件使用说明
开发板板载介绍(当前使用的测试板,以后期最终版为准) 一,实物图 硬件说明 一,开发板主控芯片说明: 1. 单片机: STM32F103RET6 2. GPRS模块: Air202 二,开发板外设说明 ...
- Sublime Text3 设置
主题:Spacegrey.sublime-theme 配色方案:Mariana 自动保存 参考:https://www.cnblogs.com/mzzz/p/6178341.html "sa ...
- gnome 3 插件设置
插件安装及管理方法 应该需提前在gnome-tweaks中打开user-theme,重启电脑后才可找到Add-ons Debian9 下在应用商店插件add-ons里进行选择安装,在应用商店已安装应用 ...
- document.write和innerHTML的区别?
document.write是直接重写整个页面,innerHTML针对所属DOM节点进行重写,效率优于document.write.
- 【cf补题记录】Codeforces Round #607 (Div. 2)
比赛传送门 这里推荐一位dalao的博客-- https://www.cnblogs.com/KisekiPurin2019/ A:字符串 B:贪心 A // https://codeforces.c ...