Noip数学整理

  • 因为某些原因, Noip对于数学方面的考纲仅停留在比较小的一部分,而这一部分在平常的做题中接触较少我做的题目太少, 为了防止NOIP爆炸, 整理一些Noip的数学知识还是有用的。

1 取模相关

  • n%p所得结果的正负由n决定,与p无关。如:7%4=3-7%4=-3-7%-4=-3 ---xun学姐
  • 欧拉定理 \(\alpha^{\phi(p)} \equiv 1 mod(p)\)
  • 当p为质数的特殊情况 $\alpha^{p - 1} \equiv 1 $
  • Noip2014式取模, 如果f(x) = 0, 那么f(x) % p = 0, 在式子中带入数字看脸计算。
  • 常数较小的取模方式
  1. void upd(int &x, int y)
  2. {
  3. x += y, x -= x >= mod ? mod : x;
  4. }

2 质数相关

质数判定

  • 根号判断比较稳
  1. bool check(int x)
  2. {
  3. for(int i = 2; i * i <= x; i++)
  4. if(x % i == 0)return false;
  5. return true;
  6. }
  • Miller robin比较骚\(-------\)chentongfei
  1. bool check(int x)
  2. {
  3. for(int i = 1; i <= 20; i++)
  4. {
  5. int op = read() % x + 1;
  6. while(op == x) op = rand() % x + 1;
  7. if(poww(op, x - 1, x) != 1) return false;
  8. }
  9. return true;
  10. }
  • 线性筛比较经典

  1. void shai()
  2. {
  3. isnt[1] = true;
  4. for(int i = 2; i <= n; i++)
  5. {
  6. if(!isnt[i]) sta[++tp] = i;
  7. for(int j = 1; j <= tp && i * sta[j] <= n; j++)
  8. {
  9. isnt[i * sta[j]] = true;
  10. if(i % sta[j] == 0) break;
  11. }
  12. }
  13. }
  • 区间筛比较没用
  1. void shai(ll l, ll r)
  2. {
  3. for(int i = 2; i * i <= r; i++)
  4. {
  5. if(!isnt[i])
  6. {
  7. for(int j = 2 * i; j * j<= r; j += i) isnt[j] = true;
  8. for(ll j = max(2ll, (l + i - 1) / i ) * i; j <= r; j += i) vis[j - l] = true;
  9. }
  10. }
  11. for(ll i = 0; i <= b - a; i++) if(!vis[i]) sta[++tp] = i + a;
  12. }

质数应用

  • 用来取模

3.基本操作

快速幂 or 慢速乘

  • ???
  • O1快速乘吼啊
  1. inline long long multi(long long x,long long y,long long mod) {
  2. long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod);
  3. return tmp<0 ? tmp+mod : tmp;
  4. }

逆元

费马小定理
  • 一定要检查一下模数是不是质数啊啊啊啊
exgcd求逆元

\(a * b \equiv 1\; mod\; m\Rightarrow a * b - m * y = 1\) 如果解出\(gcd(a, m) = 1\), 那么就存在逆元了

  1. int inv(int a, int p)
  2. {
  3. int x, y;
  4. int tmp = gcd(a, p, x, y);
  5. if(tmp != 1) return false;
  6. return (x + p) % p;
  7. }

质因数分解

根号算法
  • 枚举到根号大小就能找出所有质因子了
pollard-Robin
  • 基于随机化, 鸽笼定理, floyd判环的算法
  • 写起来挺舒适的

  1. bool robin_miller(ll n) { //判断是否素数
  2. if(n < 2) return false;
  3. if(n == 2) return true;
  4. if(!(n & 1)) return false;
  5. ll u = n - 1, t = 0;
  6. while(!(u & 1)) u >>= 1, t++;
  7. if(t >= 1 && (u & 1) == 1) {
  8. for(int i = 0; i < s; i++) {
  9. ll a = rand() % (n-1) + 1;
  10. if(witness(a, n, u, t)) return false; //不是素数
  11. }
  12. }
  13. return true; //是素数
  14. }
  15. ll gcd(ll a, ll b) {
  16. if(a == 0) return 1;
  17. if(a < 0) return gcd(-a, b);
  18. while(b) {
  19. ll t = a % b;
  20. a = b;
  21. b = t;
  22. }
  23. return a;
  24. }
  25. ll pollard_rho(ll x, ll c) {
  26. ll i = 1, x0 = rand() % x;
  27. ll y = x0;
  28. ll k = 2;
  29. for(;;) {
  30. i++;
  31. x0 = (multi_mod(x0, x0, x) + c) % x;
  32. ll d = gcd(y - x0, x);
  33. if(d != 1 && d != x) return d;
  34. if(y == x0) return x;
  35. if(i == k) {
  36. y = x0;
  37. k += k;
  38. }
  39. }
  40. }
  41. void find_fac(ll n) {
  42. if(n == 1) return;
  43. if(robin_miller(n)) {
  44. prime_factor.push_back(n);
  45. return;
  46. }
  47. ll p = n;
  48. while(p >= n) p = pollard_rho(p, rand() % (n-1) + 1);
  49. find_fac(p);
  50. find_fac(n / p);
  51. }

4.方程相关

不定方程

  • 扩展欧几里得求同余方程 \(ax + by = \gcd(a, b)\)
  1. int exgcd(int a, int b, int &x, int &y)
  2. {
  3. if(!b)
  4. {
  5. x = 1, y = 0;
  6. return a;
  7. }
  8. int ans = exgcd(b, a % b, x, y), tmp = x;
  9. x = y, y = tmp - a / b * y;
  10. return ans;
  11. }
  • 得到的解只是一组 \(ax + by = g\), 让\(x += g / b, y -= g/a\)依旧成立
  • 所以通解可以表示成\(x = x_1 + \frac{b}{\gcd(a,b)}, y = y_1 + \frac{a}{gcd(a, b)}\)
  • 对于求解\(ax + by = c\)的同余方程, 首先判断c是否是\(\gcd(a, b)\)的倍数, 不是的话则无解
  • 然后求出\(ax + by = \gcd(a, b)\) 的一组解, 之后让xy都乘以 \(g / \gcd(a, b)\)即可

线性同余方程组

  • 互质情况: 中国剩余定理
  • 求解

\[x \equiv a_1\; mod\; m_1
\]

\[x \equiv a_2\; mod\; m_2
\]

\[x \equiv a_3\; mod\; m_3
\]

\[x \equiv a_4\; mod\; m_4
\]

得到的通解可以表示成

\[x = kM + \sum_{i = 1}^{n}a_it_iM_i
\]

其中\(k \in Z\; M = \prod m_i\; M_i = \frac{M}{M_i}\; t_i = M_i^{-1}\; mod m_i\)


  1. int cn(int n)
  2. {
  3. int sum = 1, ans = 0, x, y;
  4. for(int i = 1; i <= n; i++) sum *= m[i];
  5. for(int i = 1; i <= n; i++)
  6. {
  7. int op = sum / m[i];
  8. int zz = exgcd(op, m[i], x, y);
  9. ans = (ans + g[i] * op * x) % sum;
  10. }
  11. return (sum + ans) % sum;
  12. }
  • 不互质情况, 扩展中国剩余定理
  • 感觉和中国剩余定理不是很相似, 主要是基于方程的合并
  • 首先考虑两个同余方程

\[x \equiv a_1\; mod\; m_1\\
x \equiv a_2\; mod\; m_2
\]

  • 化成另一个形式

\[x = n_1 * m_1 + a_1\\
x = n_2 * m_2 + a_2
\]

  • 联立可得

\[n_1 * m_1 + a_1 = n_2 * m_2 + a_2\\
n_1 * m_1 - n_2 * m_2 = a_2 - a_1
\]

  • 有解的前提是

\[\gcd(m_1, m_2) |(a_2 - a_1)
\]

\[d = \gcd(m_1, m_2)\\
c = a_2 - a_1
\]

\[n_1 \frac{m_1}{d} - n_2 \frac{m_2}{d} = \frac{c}{d}\\
n_1 \frac{m_1}{d} \equiv \frac{c}{d} \ mod \ \frac{m_2}{d}
\]

  • 移项

\[n_1 \equiv \frac{c}{d} * inv(\frac{m_1}{d}, \frac{m_2}{d}) \ mod\ \frac{m_2}{d}\\
n_1 = \frac{c}{d} * inv(\frac{m_1}{d}, \frac{m_2}{d}) + y_1 * \frac{m_2}{d}
\]

然后\(n_1\)代入最上面的狮子可以得到

\[x = (\frac{c}{d} * inv(\frac{m_1}{d}, \frac{m_2}{d}) + y_1 * \frac{m_2}{d}) * m_1 + a_1\\
x = m_1 * \frac{c}{d} * inv(\frac{m_1}{d}, \frac{m_2}{d}) + y_1 * \frac{m_2 m_1}{d} + a_1\\
x \equiv m_1 * \frac{c}{d} * inv(\frac{m_1}{d}, \frac{m_2}{d}) + a_1 \ mod \ \frac{m_2 m_1}{d}
\]

  • 然后就是个新方程了
  • 当然也适用于互质情况
  • 板子
  1. int ex_crt()
  2. {
  3. int a1 = a[1], m1 = m[1], a2, m2;
  4. for(int i = 2; i <= n; i++)
  5. {
  6. a2 = a[i], m2 = m[i];
  7. int c = a2 - a1;
  8. int d = gcd(m2, m1);
  9. if(c%d) return -1;
  10. ll k = inv(m1 / d, m2 / d);
  11. a1 = a1 * c / d * k + a1;
  12. m1 = m1 * m2 / d;
  13. }
  14. return a1;
  15. }

裴蜀定理

  • 对于方程 \(ax + by = c\) 有解当且仅当 \(\gcd(a,b) | c\) 可以扩展到多元, 经常被出题人用来出套路题

5.数列相关

卡特兰数

  • 前几项!!!! \(1\ 1\ 2\ 5\ 14\ 42\ 132\)
递推式

\[C_n = \sum_{i = 1}^{n - 1} C_i * C_{n - i} \\
C_n = C_{n - 1} * (4n - 2)/ (n + 1)
\]

组合式

\[h(n) = C_{2n}^{n} - C_{2n}^{n - 1}\\
h(n) = \frac{C_{2n}^{n}} { (n + 1)}
\]

意义
  • 括号化问题。矩阵链乘: P=A1×A2×A3×……×An,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?
  • 将多边行划分为三角形问题。将一个凸多边形区域分成三角形区域(划分线不交叉)的方法数
  • 出栈次序问题。一个栈(无穷大)的进栈序列为1、2、3、...、n,有多少个不同的出栈序列?
  • 给顶节点组成二叉树的问题。

组合数

求法
杨辉三角
  • 可更改性比较好, 适用于非质数取模
阶乘法
  • 预处理On, 计算一次logn, 需要On的空间
卢卡斯定理
  • 适用于模数较小且为质数

\[Lucas(n, m, p) = C_{n \% p}^{m \% p} * Lucas(n/p, m/p, p)
\]

扩展卢卡斯
  • 适用于模数较小非质数或者模数较大但是分解后因子较小
  • 相当于我们对于模数分解后分别求出在mod某个数字下组合数是多少
  • 然后使用crt合并就好了
  • 当质因数分解不干净的时候, 我们要求\(Lucas(n, m, p^t)\)这个也是个问题
  • 这里利用循环节来统计阶乘中不含p因子的数字乘积, 对于含p因子的提出来递归计算
  • Noip考这个我直播吃拖鞋
  • 贴个板子
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int t,opt;
  4. long long p[50],a[50];//存储质因数p的t次方,a存储CRT要用的余数
  5. map<long long,long long> mp;
  6. long long ji;
  7. inline long long ksm(long long x,long long y,long long mod)
  8. {
  9. long long res=1;
  10. while(y)
  11. {
  12. if(y&1)
  13. res=(res*x)%mod;
  14. x=(x*x)%mod;
  15. y>>=1;
  16. }
  17. return res;
  18. }
  19. inline void exgcd(long long a,long long b,long long &x,long long &y)
  20. {
  21. if(!b)
  22. {
  23. x=1;
  24. y=0;
  25. }
  26. else
  27. {
  28. exgcd(b,a%b,y,x);
  29. y-=a/b*x;
  30. }
  31. }
  32. inline long long inv(long long a,long long b)
  33. {
  34. long long x=0,y=0;
  35. exgcd(a,b,x,y);
  36. x=(x%b+b)%b;
  37. if(!x)
  38. x+=b;
  39. return x;
  40. }
  41. inline long long cal(long long n,long long x,long long mod)//递归计算除了x的若干次方之外的部分(第一、第三部分)
  42. {
  43. if(!n)
  44. return 1;
  45. long long ans=1;//提出来的那些不含因子x的乘积
  46. if(n/mod)//有整块的
  47. {
  48. for(int i=1;i<=mod;++i)
  49. {
  50. if(i%x)//不含因子x
  51. ans=ans*i%mod;
  52. }
  53. ans=ksm(ans,n/mod,mod);//有循环节,所以乘积用快速幂计算即可
  54. }
  55. for(int i=n/mod*mod+1;i<=n;++i)
  56. {
  57. if(i%x)
  58. ans=ans*i%mod;
  59. }
  60. return ans*cal(n/x,x,mod)%mod;//当前的不含因子x的乘积乘以递归下去求的剩余阶乘部分的结果
  61. }
  62. //计算出对于每一个质数的若干次方取模后的结果
  63. inline long long exlucas(long long m,long long n,long long x,long long mod)//x是当前质数
  64. {
  65. if(n>m)
  66. return 0;
  67. int cnt=0;
  68. for(int i=m;i;i/=x)
  69. cnt+=i/x;
  70. for(int i=n;i;i/=x)
  71. cnt-=i/x;
  72. for(int i=m-n;i;i/=x)
  73. cnt-=i/x;
  74. long long ans=ksm(x,cnt,mod)*cal(m,x,mod)%mod*inv(cal(n,x,mod),mod)%mod*inv(cal(m-n,x,mod),mod)%mod;
  75. return ans*(ji/mod)%ji*inv(ji/mod,mod)%ji;//CRT合并!
  76. }
  77. inline long long gcd(long long x,long long y)
  78. {
  79. return y?gcd(y,x%y):x;
  80. }
  1. int main()
  2. {
  3. scanf("%d",&t);
  4. while(t--)
  5. {
  6. scanf("%d",&opt);
  7. if(opt==1)
  8. {
  9. long long x,y,p;
  10. scanf("%lld%lld%lld",&x,&y,&p);
  11. printf("%lld\n",ksm(x,y,p));
  12. }
  13. else if(opt==2)
  14. {
  15. mp.clear();
  16. long long aa,b,p;
  17. int pd=0;
  18. scanf("%lld%lld%lld",&aa,&b,&p);
  19. if(b==1)
  20. {
  21. printf("0\n");
  22. pd=1;
  23. }
  24. if(pd==1)
  25. continue;
  26. long long d=gcd(aa,p),t=1,k=0;
  27. while(d!=1)
  28. {
  29. if(b%d)
  30. {
  31. printf("Math Error\n");
  32. pd=1;
  33. break;
  34. }
  35. ++k;
  36. b/=d;
  37. p/=d;
  38. t=(t*(aa/d))%p;
  39. if(b==t)
  40. {
  41. printf("%lld\n",k);
  42. pd=1;
  43. break;
  44. }
  45. d=gcd(aa,p);
  46. }
  47. if(pd==1)
  48. continue;
  49. long long m=ceil(sqrt(p)),ans;
  50. for(int j=0;j<=m;++j)
  51. {
  52. if(j==0)
  53. {
  54. ans=b%p;
  55. mp[ans]=j;
  56. continue;
  57. }
  58. ans=(ans*aa)%p;
  59. mp[ans]=j;
  60. }
  61. long long x=ksm(aa,m,p);
  62. ans=t;
  63. for(int i=1;i<=m;++i)
  64. {
  65. ans=(ans*x)%p;
  66. if(mp[ans])
  67. {
  68. x=i*m-mp[ans];
  69. printf("%lld\n",x+k);
  70. pd=1;
  71. break;
  72. }
  73. }
  74. if(!pd)
  75. printf("Math Error\n");
  76. }
  77. else
  78. {
  79. long long x,y,mod;
  80. scanf("%lld%lld%lld",&x,&y,&mod);
  81. ji=mod;//mod就是CRT的那个因子乘积和!
  82. if(mod==1)
  83. {
  84. printf("0\n");
  85. continue;
  86. }
  87. memset(p,0,sizeof(p));
  88. memset(a,0,sizeof(a));
  89. int cnt=0;//记录质数个数
  90. for(int i=2;i*i<=mod;++i)
  91. {
  92. if(mod%i==0)
  93. {
  94. p[++cnt]=1;
  95. while(mod%i==0)
  96. {
  97. p[cnt]*=i;
  98. mod/=i;//把当前因子除掉对看是否是后面数的倍数无影响
  99. }
  100. a[cnt]=exlucas(y,x,i,p[cnt]);
  101. }
  102. }
  103. if(mod>1)
  104. {
  105. p[++cnt]=mod;
  106. a[cnt]=exlucas(y,x,mod,mod);
  107. }
  108. long long res=0;
  109. for(int i=1;i<=cnt;++i)
  110. res=(res+a[i])%ji;
  111. printf("%lld\n",res);
  112. }
  113. }
  114. return 0;
  115. }
常见模型和性质
奇偶性
  • 当且仅当n & m == m时 \(C_n^m\) 为奇数
插板法
  • n种元素,每种可选择任意次或者不选,共选m

\[C_{n +m - 1} ^{n - 1}
\]

全错排公式

\[f[i] = (i - 1)(f[i - 1] + f[i - 2])
\]

  • 情况1:插入第i个元素时,前i-1个已经错位排好,则选择其中任意一个与第i个互换一定满足要求,选择方法共i-1种,前i-1位错排f[i-1]种,记f[i-1]*(i-1)

  • 情况2:插入第i个元素时,前i-1个中恰有一个元素a[j]使得a[j]=j,其他i-2个错位排好,则将i与j交换,j在i-2位中的插入共i-1种,前i-2位错排f[i-2]种,记f[i-2]*(i-1)

6.函数相关

  • Noip函数???
  • 貌似只有一次函数合二次函数了吧QAQ

Noip数学整理的更多相关文章

  1. NOIP数学相关模板整理

    $O(n)$递推求逆元 #include<cstdio> #include<cstring> #include<algorithm> using namespace ...

  2. NOIP模板整理计划

    先占个坑 [update]noip结束了,弃了 一.图论 1.单源最短路 洛谷P3371 (1)spfa 已加SLF优化 #include <iostream> #include < ...

  3. noip考点整理(应该不是很完整……)

    部分来自百度百科.其他的博客 一.必须会的 1.暴力: DFS.BFS.灌水法搜索.回溯搜索.记忆化搜索.启发式搜索.最优性剪枝.可行性剪枝 2.贪心 3.模拟 4.骗分 二.基础算法 1.图论:SP ...

  4. NOIp 数学知识点总结

    推荐阅读 NOIp 基础数论知识点总结: https://www.cnblogs.com/greyqz/p/number.html 排列组合 常用公式 排列:\[\displaystyle A_n^m ...

  5. $\rm{NOIp}$板子整理

    怎么说呢,整理这个的目的就是为了有个简约的\(list\),方便以后查阅,复习起来不至于太吃力. 并且--好像重温一遍所有,会更有一些新的认识.这也算是对我所学的一点整理了吧. 一.并查集的两种方式 ...

  6. bzoj 3293 数学整理

    和1045一模一样,找到这道题的时候还愣了下神,最后发现样例都是 一样的,直接粘了1045的代码,具体题解看 http://www.cnblogs.com/BLADEVIL/p/3468729.htm ...

  7. bzoj1257 数学整理二分查询

    2013-11-15 21:55 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1257 要求求sigma k mod i(i<=n) ...

  8. 【模板】【学习笔记】noip数学

    一.素数 欧拉筛 void prime(){ check[]=; ;i<=n;i++){ if(!check[i])prim[++cnt]=i;//这个if语句后面没有大括号!! ;j<= ...

  9. noip数学

    一.取模运算 (1)定义 给定一个正整数p和一个整数n 一定存在此等式 n=k*p+r;其中k,r是整数,r大于等于0小于p 称k是n除以p的商,r为n除以p的余数 说明:同余式 正整数a,b对p取模 ...

随机推荐

  1. vue 下实现 echarts 全国到省份的地图下钻

    vue 下实现 echarts 全国到省份的地图下钻 项目地址:https://github.com/cag2050/vue_echarts_v3_demo

  2. Centos6 rpm 安装mysql5.5(转)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/macfac/article/details/51868712 0. 到官网下载好,想要安装的rpm包 ...

  3. LOJ 3056 「HNOI2019」多边形——模型转化+树形DP

    题目:https://loj.ac/problem/3056 只会写暴搜.用哈希记忆化之类的. #include<cstdio> #include<cstring> #incl ...

  4. Spark官网资料学习网址

    百度搜索Spark: 这一个是Spark的官网网址,你可以在上面下载相关的安装包等等. 这一个是最新的Spark的文档说明,你可以查看如何安装,如何编程,以及含有对应的学习资料.

  5. Python依赖打包发布详细

    http://www.cnblogs.com/mywolrd/p/4756005.html 将Python脚本打包成可执行文件   Python是一个脚本语言,被解释器解释执行.它的发布方式: .py ...

  6. PHP 下载中文乱码解决

    利用 iconv() 函数解决乱码 $file_name = iconv("utf-8","gb2312",$file_name); 原文链接 http://m ...

  7. pytest.6.Parametrize Fixture

    From: http://www.testclass.net/pytest/parametrizing_fixture/ 背景 @pytest.mark.parametrize 装饰器可以让我们每次参 ...

  8. MongDB备份error: boost::filesystem::create_directory

    用dump 备份一直提示一个error "error: boost::filesystem::create_directory: The filename, directory name, ...

  9. shell文件描述符和重定向

    1.文件描述符是与一个打开的文件或数据流相关联的整数.文件描述符0,1,2是系统预留的. 0 --------stdin(标准输入) 1 --------stdout(标准输出) 2--------- ...

  10. SecureCRT & SecureFx 绿色破解版

    租了腾讯云的服务器,是 ubuntu 版的,需要用到 SecureCRT 工具来远程链接,但是连接的只是控制台,只能输入命令操作,如果要下载文件什么的,就很麻烦,这时可以使用 SecureFx 来传输 ...