<更新提示>

<第一次更新>


<正文>

简单数论

质因子分解

素性测试

素性测试指的是对一个正整数是否为质数的判定,一般来说,素性测试有两种算法:

\(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\)卷积为:

\[(f\times g)(n)=\sum_{d|n}f(d)g(\frac{n}{d})
\]

狄利克雷卷积的性质

\(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\)。

证明:

\[g=I\times f\\ \mu\times g =\mu \times I \times f\\\mu \times g=\epsilon \times f=f
\]

底和顶

\(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\)的前缀和。

公式:

\[\sum_{i=1}^nf(i)=\sum_{i=1}^n(f\times g)(i)-\sum_{i=2}^ng(i)\sum_{j=1}^{\lfloor \frac{n}{i} \rfloor}f(j)
\]

另一种形式,设\(S(n)=\sum_{i=1}^nf(i)\),那么有:

\[S(n)=\sum_{i=1}^n(f\times g)(i)-\sum_{i=2}^ng(i)S \left (\lfloor \frac{n}{i} \rfloor \right )
\]

可以用整除分块和记忆化搜索来计算,当我们线性筛预处理前\(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』的更多相关文章

  1. 『正睿OI 2019SC Day8-Day17』

    于是就迎来\(10\)天的自闭考试了,每天写点小总结吧. Day8 第一天就很自闭啊,考题分别是数学题+建模题+图论. 前两道题都没有什么算法,但是难度还是有的,于是就做不太出来,特别是第一题.第二题 ...

  2. 『正睿OI 2019SC Day5』

    网络流 网络流的定义 一个流网络\(G=(V,E)\)为一张满足以下条件的有向图: 每一条边有一个非负容量,即对于任意\(E\)中的\((u,v)\) , 有\(c(u,v)\geq0\). 如果\( ...

  3. 『正睿OI 2019SC Day4』

    总结 今天是一场欢乐的\(ACM\)比赛,于是我队得到了全场倒数的好排名. 好吧,其实还是怪自己不能怪队友啦.对于\(ACM\),可能最主要的还是经验不足,导致比赛的时候有点紧张.虽然队友为了磕一道题 ...

  4. 『正睿OI 2019SC Day1』

    概率与期望 总结 老师上午几乎是在讲数学课,没有讲什么和\(OI\)有关的题目,所以我就做了一点笔记. 到了下午,老师讲完了有关知识点和经典模型,就开始讲例题了.前两道例题是以前就做过的,所以没有什么 ...

  5. 『正睿OI 2019SC Day6』

    动态规划 \(dp\)早就已经是经常用到的算法了,于是老师上课主要都在讲题.今天讲的主要是三类\(dp\):树形\(dp\),计数\(dp\),\(dp\)套\(dp\).其中计数\(dp\)是我很不 ...

  6. 『正睿OI 2019SC Day3』

    容斥原理 容斥原理指的是一种排重,补漏的计算思想,形式化的来说,我们有如下公式: \[\left | \bigcup_{i=1}^nS_i \right |=\sum_{i}|S_i|-\sum_{i ...

  7. 『正睿OI 2019SC Day2』

    分治 普通分治 普通分治是指针对序列或平面问题的分治算法. 思想 普通分治的思想是指将一个序列问题或平面问题通过某种划分方式划分为若干个子问题,直到子问题规模足够小,可以直接回答,再通过合并得到原问题 ...

  8. 10.23 正睿停课训练 Day7

    目录 2018.10.23 正睿停课训练 Day7 A 矩形(组合) B 翻转(思路) C 求和(思路 三元环计数) 考试代码 B1 B2 C 2018.10.23 正睿停课训练 Day7 期望得分: ...

  9. 正睿OI DAY3 杂题选讲

    正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...

随机推荐

  1. Visual Studio调试到OpenCV源码中

    TL;DR VS2015下,build-farm/vs2015-x64/bin/Debug/目录,*.pdb文件,都拷贝到install/x64/vc14/bin目录,就可以调试进去opencv源码了 ...

  2. centos7 安装 ffmpeg

    升级系统 yum install epel-release -yyum update -y 安装Nux Dextop Yum源 由于centos 没有官方软件包,我们可以使用第三方YUM源(Nux D ...

  3. Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)

    题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...

  4. NOIP 2013 积木大赛

    洛谷 P1969 积木大赛 洛谷传送门 JDOJ 2229: [NOIP2013]积木大赛 D2 T1 JDOJ传送门 题目描述 春春幼儿园举办了一年一度的"积木大赛".今年比赛的 ...

  5. MongoDB executionStats 详细分步查询计划与分步时间(转载)

    mongodb性能分析方法:explain() 为了演示的效果,我们先来创建一个有200万个文档的记录.(我自己的电脑耗了15分钟左右插入完成.如果你想插更多的文档也没问题,只要有耐心等就可以了.) ...

  6. K8s集群认证之RBAC

    kubernetes认证,授权概括总结: RBAC简明总结摘要:API Server认证授权过程: subject(主体)----->认证----->授权[action(可做什么)]--- ...

  7. Spring Boot 知识笔记(Filter过滤器)

    Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 htm ...

  8. Unchecked runtime.lastError: The message port closed before a response was received.

    这是由于某个 Chrome 扩展程序造成的. 打开 chrome://extensions/,逐一关闭排查.我这边是由于“迅雷下载支持”这个扩展引起的,将其关闭即可.

  9. GPS和LOAM的pose之间建立edge

    基于时间戳一致原理,在与PG的timestamp邻近的的两个LOAM的pose中插值出一个虚拟的LOAM pose PG' ,其timestamp = PG的timestamp. 然后GPS的pose ...

  10. 2018-2019-2 网络对抗技术 20165230 Exp8 Web基础

    目录 实验目的 实验内容 实验步骤 (一)Web前端HTML Apache HTML编程 (二) Web前端javascipt 基础知识理解 JavaScript编程 (三)Web后端:MySQL基础 ...