NOIP2018模板总结【数学】
质因数分解
//质因数分解
int prime[MAXN], tim[MAXN], cnt;
void Divide(int N)
{
printf("%d = ", N);
for(int i = 2; i * i <= N; i++) if(N % i == 0)
{
prime[++cnt] = i;
while(N % i == 0) N /= i, tim[cnt]++;
}
if(N > 1) prime[++cnt] = N, tim[cnt] = 1;
printf("%d^%d", prime[1], tim[1]);
for(int i = 2; i <= cnt; i++)
printf(" * %d^%d", prime[i], tim[i]);
}
线性筛素数/欧拉函数
线性筛素数/欧拉函数
int phi[MAXN], prime[MAXP], cnt;
bool vis[MAXN];
void Prime(int N)
{
phi[1] = 1;
for(int i = 2; i <= N; i++)
{
if(!vis[i]) prime[++cnt] = i, phi[i] = i-1;
for(int j = 1; j <= cnt && i*prime[j] <= N; j++)
{
vis[i*prime[j]] = true;
if(i % prime[j] == 0) { phi[i*prime[j]] = phi[i] * prime[j]; break; }
phi[i*prime[j]] = phi[i] * (prime[j]-1);
}
}
}
Miller-Robin大素数测试/快速幂/快速乘
//Miller-Robin大素数测试
#define LL long long
//O(1)快速乘(模)
LL kmul(LL a,LL b,LL P)
{
a = (a % P + P) % P,b = (b % P + P) % P;
return ((a * b - (LL)((long double)a / P * b + 1e-6) * P) % P + P) % P;
}
//O(logn)快速幂
LL kpow(LL a, LL b, LL mod)
{
LL ret = 1;
while(b)
{
if(b & 1) ret = kmul(ret, a, mod);
a = kmul(a, a, mod); b >>= 1;
}
return ret;
}
bool Mil_Rb(LL N, LL a)
{
LL d = N-1; int s = 0;
while(!(d & 1))
d >>= 1, s++;
LL t = kpow(a, d, N);
if(t == 1 || t == -1) return true;
for(int i = 0; i < s; i++)
{
if(t == N-1) return 1;
t = kmul(t, t, N);
}
return 0;
}
bool isPrime(LL N)
{
if(N == 2) return true;
if(N == 1 || !(N & 1)) return false;
LL a[5] = { 2, 3, 5, 7, 11 };
for(int i = 0; i < 5; i++)
{
if(N == a[i]) return true;
if(!(N % a[i])) return false;
if(N > a[i] && !Mil_Rb(N, a[i])) return false;
}
return true;
}
gcd & lcm
//gcd & lcm
LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
LL lcm(LL a, LL b) { return a / gcd(a, b) * b; }
exgcd
//a*x + b*y = b*y + (a%b)*x + (a/b)*b*x
// = b*(y+x*(a/b)) + (a%b)*x
#define LL long long
void exgcd(LL a, LL b, LL &x, LL &y, LL &gcd)
{
if(!b) { x = 1, y = 0; gcd = a; return; }
exgcd(b, a%b, y, x, gcd); y -= x * (a/b);
}
中国剩余定理
//中国剩余定理
void exgcd(int a, int b, int &x, int &y)
{
if(!b) { x = 1; y = 0; return; }
exgcd(b, a%b, y, x); y -= x*(a/b);
}
int CRT(int *W, int *B, int k) // W > B
{
int x, y, mulsum = 1, ans = 0;
for(int i = 1; i <= k; i++)
mulsum *= W[i];
for(int i = 1; i <= k; i++)
{
int M = mulsum/W[i];
exgcd(W[i], M, x, y);
ans = (ans + y*M*B[i]) % mulsum;
}
if(ans < 0) ans += mulsum;
return ans;
}
卡特兰数
// ksm(a, mod-2)在mod为素数的情况下≡a^(-1),即a在mod下的逆元
//Catalan
const int MAXN = 5005;
int Catalan[MAXN];
int pre()
{
Catalan[0] = 1;
for(int i = 1; i < MAXN; i++)
for(int j = 0; j < i; j++)
Catalan[i] = (Catalan[i] + (LL)Catalan[j] * Catalan[i-j-1] %mod) % mod;
// or
for(int i = 1; i < MAXN; i++)
Catalan[i] = (LL)Catalan[i-1] * (4*i-2) % mod * ksm(n+1, mod-2);
}
int Catalan(int n)
{
return C(n<<1, n) * ksm(n+1, mod-2);
// or
return (C(n<<1, n) - C(n<<1, n-1)) % mod + mod) % mod;
}
康托展开式
LL Fac[21];
//预处理阶乘(20!在longlong范围内而21!爆longlong)
inline void init()
{
Fac[0] = Fac[1] = 1;
for(int i = 2; i <= 20; i++)
Fac[i] = Fac[i-1] * i;
}
//康托展开
inline LL cantor(vector<int>A, int n)//即求字典序小于此排列的个数
{
LL ret = 0; //答案从0 ~ n!-1
for(int i = 0; i < n; i++)
{
int k = 0;
for(int j = i+1; j < n; j++)//求逆序对
if(A[i] > A[j]) k++;
ret += Fac[n-i-1] * k;
}
return ret;
}
//逆康托
vector<int> decantor(LL x, int n)
{
vector<int>left, ret;
for(int i = 1; i <= n; i++) left.push_back(i); //存剩下的数字
for(int i = n; i >= 1; i--)
{
int q = x/Fac[i-1];
x %= Fac[i-1];
ret.push_back(left[q]);
left.erase(left.begin()+q); //删除
}
return ret;
}
N的(随机/全)排列
//Random
srand(time(NULL));
int num[MAXN], n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
num[i] = i;
random_shuffle(num + 1, num + n + 1);
for(int i = 1; i <= n; i++)
printf("%d ", num[i]);
//All
int num[MAXN], n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
num[i] = i;
do {
for(int i = 1; i <= n; i++)
printf("%d ", num[i]);
putchar('\n');
}while(next_permutation(num + 1, num + n + 1));
N的R排列
int seq[MAXN], N, R;
inline void Print()
{
for(int i = 1; i <= R; i++)
printf("%d%c", seq[i], i == R ? '\n' : ' ');
}
bool vis[MAXN];
inline void dfs(int now) //N的R排列
{
if(now > R)
{
Print();
return;
}
for(int i = 1; i <= N; i++)
if(!vis[i])
{
vis[i] = 1;
seq[now] = i; dfs(now+1);
vis[i] = 0;
}
}
N的R排列(可重复)
int seq[MAXN], N, R;
inline void Print()
{
for(int i = 1; i <= R; i++)
printf("%d%c", seq[i], i == R ? '\n' : ' ');
}
inline void dfs(int now) //N的R排列(可重复)
{
if(now > R)
{
Print();
return;
}
for(int i = 1; i <= N; i++)
seq[now] = i, dfs(now+1);
}
N的R组合(可重复)
int seq[MAXN], N, R;
inline void Print()
{
for(int i = 1; i <= R; i++)
printf("%d%c", seq[i], i == R ? '\n' : ' ');
}
inline void dfs(int now) //N的R组合(可重复)
{
if(now > R)
{
Print();
return;
}
for(int i = max(seq[now-1], 1); i <= N; i++)
seq[now] = i, dfs(now+1);
}
第一类斯特林数(有/无符号) 
LL Su[MAXN][MAXN]; //无符号第一类斯特林数
LL Ss[MAXN][MAXN]; //有符号第一类斯特林数
inline void init()
{
Su[0][0] = 1; //CAUTION
for(int i = 1; i < MAXN; i++) //即n个不同元素构成m个圆排列的方案数
{
Su[i][0] = 0; //CAUTION
for(int j = 1; j <= i; j++)
Su[i][j] = (Su[i-1][j-1] + Su[i-1][j]*(i-1)) % mod;
}
Ss[0][0] = 1; //CAUTION
for(int i = 1; i < MAXN; i++)
{
Ss[i][0] = 0; //CAUTION
for(int j = 1; j <= i; j++)
Ss[i][j] = (Ss[i-1][j-1] - Ss[i-1][j]*(i-1)) % mod;
}
}
“pascal”三角形
二项式系数
可以构成一个杨辉三角(pascal三角形)。同样第一类Stirling数同样也可以构成一个三角,可以由此分析其性质。
| 无符号Stirling数 | 有符号Stirling数 | |
| n=0 | 1 | 1 |
| n=1 | 0 1 | 0 1 |
| n=2 | 0 1 1 | 0 -1 1 |
| n=3 | 0 2 3 1 | 0 2 -3 1 |
| n=4 | 0 6 11 6 1 | 0 -6 11 -6 1 |
| n=5 | 0 24 50 35 10 1 | 0 24 -50 35 -10 1 |
| n=6 | 0 120 274 225 85 15 1 | 0 -120 274 -225 85 -15 1 |
| n=7 | 0 720 1764 1624 735 175 21 1 | 0 720 -1764 1624 -735 175 -21 1 |
性质
无符号Stirling数有如下性质:
① 
② 
③ 
④ 
⑤ 
⑥ 
⑦ 
⑧ 
有符号stirling性质类似:
① 
②
,注意 
以上摘自万能的百度百科
第二类斯特林数 
LL S[MAXN][MAXN];
inline void init()
{
S[0][0] = 1;
for(int i = 1; i < MAXN; i++)
{
S[i][0] = 0;
for(int j = 1; j <= i; j++)
S[i][j] = (S[i-1][j-1] + S[i-1][j] * j) %mod;
}
}
“pascal”三角形
| n=0 | 1 |
| n=1 | 0 1 |
| n=2 | 0 1 1 |
| n=3 |
0 1 3 1 |
| n=4 |
0 1 7 6 1 |
| n=5 |
0 1 15 25 10 1 |
| n=6 |
0 1 31 90 65 15 1 |
| n=7 |
0 1 63 301 350 140 21 1 |
| n=8 |
0 1 127 966 1701 1050 266 28 1 |
| n=9 |
0 1 255 3025 7770 6951 2646 462 36 1 |
性质
①
注意 
② 
③ 
④ 
⑤ 
⑥ 
⑦ 
⑧ 
⑨
,
是贝尔数。
⑩
由
推出
其中Ⅰ.
实际上为【n个不同的球,放入m个有区别的盒子,允许盒子为空】的方案数
Ⅱ.
为【n个不同的球,放入m个无区别的盒子,允许盒子为空】的方案数
因为Ⅰ的盒子有区别,所以用Ⅱ乘上排列即为Ⅰ,Ⅰ=
。
又因为Ⅰ中每个球有m种选择且相互独立,Ⅰ= 
∵Ⅰ = Ⅰ
∴ 
推论
(1) 若n<m,
,因为S(n, m) = 0
(2)
,因为S(m, m) = 1
以上摘自万能的百度百科
贝尔数
LL B[MAXN];
void init()
{
for(int i = 1; i < MAXN; i++)
{
for(int j = 0; j < i; j++) //CAUTION
B[i] = (B[i] + B[j]*C(i, j))%mod;//C -> 组合数
or
for(int j = 1; j <= i; j++) //CAUTION
B[i] = (B[i] + S(i, j))%mod;//S -> 第二类斯特林数
}
}
//同时适合"Touchard同余"
//B(n+p) ≡ B(n) + B(n+1) (mod p)
Lucas定理
// C(n, m) ≡ C(n/p, m/p) * C(n%p, m%p) (mod p) p为质数
LL Lucas(LL n, LL m, LL p)
{
return Lucas(n/p, m/p) * C(n%p, m%p) % p;
}
枚举子集(二进制输出)
int s, all;
scanf("%d", &all); s = all;
do {
cout<<bitset<N>(s)<<endl;
}while(s && (--s&=all, 1));
NOIP2018模板总结【数学】的更多相关文章
- D. Mahmoud and Ehab and another array construction task 因子分界模板+贪心+数学
D. Mahmoud and Ehab and another array construction task 因子分解模板 题意 给出一个原序列a 找出一个字典序大于a的序列b,使得任意 \(i!= ...
- smarty应用1 之 模板进行数学运算,保留小数位数
例子1 乘法除法运算: 1格式:{$number|number_format} 保留小数点后2位小数. {$v/$total*100|string_format:"%0.2f"|c ...
- 模板引擎(smarty)知识点总结四
/* smarty 引入对象 */ require_once 'libs/Smarty.class.php'; require 'MySmarty.class.php'; $msma = ne ...
- NOIP2018 - 暑期博客整理
暑假写的一些博客复习一遍.顺便再写一遍或者以现在的角度补充一点东西. 盛暑七月 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士 比较经典的基环外向树dp.可以借鉴的 ...
- luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)
手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/suncongbo/article/details/84487306 题目链接: ht ...
- 硕士研究生入学考试复试试卷答案.tex
%该模板用于数学答题 \documentclass[UTF8]{ctexart}%[中文编码 UTF8] \usepackage{fancyhdr}%{页眉页脚页码} \pagestyle{fancy ...
- 2011 ACM/ICPC 成都赛区(为2013/10/20成都现场赛Fighting)
hdu 4111 Alice and Bob 博弈:http://www.cnblogs.com/XDJjy/p/3350014.html hdu 4112 Break the Chocolate ...
- 用MathType编辑反三角函数的方法
在使用文档写数学类的文章时候,常常会涉及到一些数学公式,由于数学公式中包含了很多的数学符号,如果使用文档自带的公式编辑器往往会发现很多的符号都不全或者不符合自己的要求.这个时候就需要一款专业的数学公式 ...
- latex学习
第一段代码 \documentclass{article} \usepackage{ctex} \begin{document} \section{文字} 特可爱模板 \section{数学} \[ ...
随机推荐
- 卸载桌面产品,弹出错误框The Windows Installer service could not be accessed
卸载程序报这个错误: https://helpdeskgeek.com/how-to/how-to-fix-the-windows-installer-service-could-not-be-acc ...
- Kafka工具教程 - Apache Kafka中的2个重要工具
1.目标 - 卡夫卡工具 在我们上一期的Kafka教程中,我们讨论了Kafka Workflow.今天,我们将讨论Kafka Tool.首先,我们将看到卡夫卡的意义.此外,我们将了解两个Kafka工具 ...
- Word 中直引号和弯引号的相互替换
直引号替换成弯引号 弯引号替换成直引号 未完 ...... 点击访问原文(进入后根据右侧标签,快速定位到本文)
- 解决SQL server 18740、18456登录失败问题
第一步:使用window管理员用户登录SQL server 第二步:如下图步骤(开始配置sa默认用户) 第三步:选择角色类型 第四步:选择和配置用户映射的数据库 第五步:授予允许连接,并开启登录权限 ...
- php位运算及其高级应用
我们之前学过逻辑与(&&) 条件1 && 条件2 当两边条件同时成立时候返回1 逻辑或(||) 条件1 || 条件2 当两边条件只要有一 ...
- 微信H5页面前端开发,大多数人都会遇到的几个兼容性坑
最近给公司微信公众号,写了微信h5业务页面,总结分享一下前端开发过程中的几个兼容性坑,项目直接拿的公司页面,所以下文涉及图片都模糊处理了. 1.ios端兼容input光标高度 问题详情描述:input ...
- GOF 的23种JAVA常用设计模式总结 01 设计模式的概念分类和功能
1.简介 软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.它描述了在软件设计过程中的一些不断重复发生的 ...
- 2.5_Database Interface ODBC数据源及案例
分类 用户数据源 用户创建的数据源,称为“用户数据源”.此时只有创建者才能使用,并且只能在所定义的机器上运行.任何用户都不能使用其他用户创建的用户数据源. 系统数据源 所有用户在Windows下以服务 ...
- Alfred神器使用手册【转】
我曾经耗费巨大的精力,试图在计算机的使用效率上找到一条优化的捷径,一直以来都收效甚微.直到遇上 alfred,它强大的工作流机制,彻底解决了输入输出的痛点,极大的减少了程序之间的切换成本和重复按键成本 ...
- python3基础之“小练习(1)”
(一)打印3个不同的字符 # a=int("123") # b="123" # c=1.2 # print(type(a),a) # print(type(b) ...