Noip数学整理
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, 在式子中带入数字看脸计算。
- 常数较小的取模方式
void upd(int &x, int y)
{
x += y, x -= x >= mod ? mod : x;
}
2 质数相关
质数判定
- 根号判断比较稳
bool check(int x)
{
for(int i = 2; i * i <= x; i++)
if(x % i == 0)return false;
return true;
}
- Miller robin比较骚\(-------\)chentongfei
bool check(int x)
{
for(int i = 1; i <= 20; i++)
{
int op = read() % x + 1;
while(op == x) op = rand() % x + 1;
if(poww(op, x - 1, x) != 1) return false;
}
return true;
}
- 线性筛比较经典
void shai()
{
isnt[1] = true;
for(int i = 2; i <= n; i++)
{
if(!isnt[i]) sta[++tp] = i;
for(int j = 1; j <= tp && i * sta[j] <= n; j++)
{
isnt[i * sta[j]] = true;
if(i % sta[j] == 0) break;
}
}
}
- 区间筛比较没用
void shai(ll l, ll r)
{
for(int i = 2; i * i <= r; i++)
{
if(!isnt[i])
{
for(int j = 2 * i; j * j<= r; j += i) isnt[j] = true;
for(ll j = max(2ll, (l + i - 1) / i ) * i; j <= r; j += i) vis[j - l] = true;
}
}
for(ll i = 0; i <= b - a; i++) if(!vis[i]) sta[++tp] = i + a;
}
质数应用
- 用来取模
3.基本操作
快速幂 or 慢速乘
- ???
- O1快速乘吼啊
inline long long multi(long long x,long long y,long long mod) {
long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod);
return tmp<0 ? tmp+mod : tmp;
}
逆元
费马小定理
- 一定要检查一下模数是不是质数啊啊啊啊
exgcd求逆元
\(a * b \equiv 1\; mod\; m\Rightarrow a * b - m * y = 1\) 如果解出\(gcd(a, m) = 1\), 那么就存在逆元了
int inv(int a, int p)
{
int x, y;
int tmp = gcd(a, p, x, y);
if(tmp != 1) return false;
return (x + p) % p;
}
质因数分解
根号算法
- 枚举到根号大小就能找出所有质因子了
pollard-Robin
- 基于随机化, 鸽笼定理, floyd判环的算法
- 写起来挺舒适的
bool robin_miller(ll n) { //判断是否素数
if(n < 2) return false;
if(n == 2) return true;
if(!(n & 1)) return false;
ll u = n - 1, t = 0;
while(!(u & 1)) u >>= 1, t++;
if(t >= 1 && (u & 1) == 1) {
for(int i = 0; i < s; i++) {
ll a = rand() % (n-1) + 1;
if(witness(a, n, u, t)) return false; //不是素数
}
}
return true; //是素数
}
ll gcd(ll a, ll b) {
if(a == 0) return 1;
if(a < 0) return gcd(-a, b);
while(b) {
ll t = a % b;
a = b;
b = t;
}
return a;
}
ll pollard_rho(ll x, ll c) {
ll i = 1, x0 = rand() % x;
ll y = x0;
ll k = 2;
for(;;) {
i++;
x0 = (multi_mod(x0, x0, x) + c) % x;
ll d = gcd(y - x0, x);
if(d != 1 && d != x) return d;
if(y == x0) return x;
if(i == k) {
y = x0;
k += k;
}
}
}
void find_fac(ll n) {
if(n == 1) return;
if(robin_miller(n)) {
prime_factor.push_back(n);
return;
}
ll p = n;
while(p >= n) p = pollard_rho(p, rand() % (n-1) + 1);
find_fac(p);
find_fac(n / p);
}
4.方程相关
不定方程
- 扩展欧几里得求同余方程 \(ax + by = \gcd(a, b)\)
int exgcd(int a, int b, int &x, int &y)
{
if(!b)
{
x = 1, y = 0;
return a;
}
int ans = exgcd(b, a % b, x, y), tmp = x;
x = y, y = tmp - a / b * y;
return ans;
}
- 得到的解只是一组 \(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)\)即可
线性同余方程组
- 互质情况: 中国剩余定理
- 求解
\]
\]
\]
\]
得到的通解可以表示成
\]
其中\(k \in Z\; M = \prod m_i\; M_i = \frac{M}{M_i}\; t_i = M_i^{-1}\; mod m_i\)
int cn(int n)
{
int sum = 1, ans = 0, x, y;
for(int i = 1; i <= n; i++) sum *= m[i];
for(int i = 1; i <= n; i++)
{
int op = sum / m[i];
int zz = exgcd(op, m[i], x, y);
ans = (ans + g[i] * op * x) % sum;
}
return (sum + ans) % sum;
}
- 不互质情况, 扩展中国剩余定理
- 感觉和中国剩余定理不是很相似, 主要是基于方程的合并
- 首先考虑两个同余方程
x \equiv a_2\; mod\; m_2
\]
- 化成另一个形式
x = n_2 * m_2 + a_2
\]
- 联立可得
n_1 * m_1 - n_2 * m_2 = a_2 - a_1
\]
- 有解的前提是
\]
- 设
c = a_2 - a_1
\]
- 则
n_1 \frac{m_1}{d} \equiv \frac{c}{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 = 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}
\]
- 然后就是个新方程了
- 当然也适用于互质情况
- 板子
int ex_crt()
{
int a1 = a[1], m1 = m[1], a2, m2;
for(int i = 2; i <= n; i++)
{
a2 = a[i], m2 = m[i];
int c = a2 - a1;
int d = gcd(m2, m1);
if(c%d) return -1;
ll k = inv(m1 / d, m2 / d);
a1 = a1 * c / d * k + a1;
m1 = m1 * m2 / d;
}
return a1;
}
裴蜀定理
- 对于方程 \(ax + by = c\) 有解当且仅当 \(\gcd(a,b) | c\) 可以扩展到多元, 经常被出题人用来出套路题
5.数列相关
卡特兰数
- 前几项!!!! \(1\ 1\ 2\ 5\ 14\ 42\ 132\)
递推式
C_n = C_{n - 1} * (4n - 2)/ (n + 1)
\]
组合式
h(n) = \frac{C_{2n}^{n}} { (n + 1)}
\]
意义
- 括号化问题。矩阵链乘: P=A1×A2×A3×……×An,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?
- 将多边行划分为三角形问题。将一个凸多边形区域分成三角形区域(划分线不交叉)的方法数
- 出栈次序问题。一个栈(无穷大)的进栈序列为1、2、3、...、n,有多少个不同的出栈序列?
- 给顶节点组成二叉树的问题。
组合数
求法
杨辉三角
- 可更改性比较好, 适用于非质数取模
阶乘法
- 预处理On, 计算一次logn, 需要On的空间
卢卡斯定理
- 适用于模数较小且为质数
\]
扩展卢卡斯
- 适用于模数较小非质数或者模数较大但是分解后因子较小
- 相当于我们对于模数分解后分别求出在mod某个数字下组合数是多少
- 然后使用crt合并就好了
- 当质因数分解不干净的时候, 我们要求\(Lucas(n, m, p^t)\)这个也是个问题
- 这里利用循环节来统计阶乘中不含p因子的数字乘积, 对于含p因子的提出来递归计算
- Noip考这个我直播吃拖鞋
- 贴个板子
#include <bits/stdc++.h>
using namespace std;
int t,opt;
long long p[50],a[50];//存储质因数p的t次方,a存储CRT要用的余数
map<long long,long long> mp;
long long ji;
inline long long ksm(long long x,long long y,long long mod)
{
long long res=1;
while(y)
{
if(y&1)
res=(res*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return res;
}
inline void exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b)
{
x=1;
y=0;
}
else
{
exgcd(b,a%b,y,x);
y-=a/b*x;
}
}
inline long long inv(long long a,long long b)
{
long long x=0,y=0;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if(!x)
x+=b;
return x;
}
inline long long cal(long long n,long long x,long long mod)//递归计算除了x的若干次方之外的部分(第一、第三部分)
{
if(!n)
return 1;
long long ans=1;//提出来的那些不含因子x的乘积
if(n/mod)//有整块的
{
for(int i=1;i<=mod;++i)
{
if(i%x)//不含因子x
ans=ans*i%mod;
}
ans=ksm(ans,n/mod,mod);//有循环节,所以乘积用快速幂计算即可
}
for(int i=n/mod*mod+1;i<=n;++i)
{
if(i%x)
ans=ans*i%mod;
}
return ans*cal(n/x,x,mod)%mod;//当前的不含因子x的乘积乘以递归下去求的剩余阶乘部分的结果
}
//计算出对于每一个质数的若干次方取模后的结果
inline long long exlucas(long long m,long long n,long long x,long long mod)//x是当前质数
{
if(n>m)
return 0;
int cnt=0;
for(int i=m;i;i/=x)
cnt+=i/x;
for(int i=n;i;i/=x)
cnt-=i/x;
for(int i=m-n;i;i/=x)
cnt-=i/x;
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;
return ans*(ji/mod)%ji*inv(ji/mod,mod)%ji;//CRT合并!
}
inline long long gcd(long long x,long long y)
{
return y?gcd(y,x%y):x;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&opt);
if(opt==1)
{
long long x,y,p;
scanf("%lld%lld%lld",&x,&y,&p);
printf("%lld\n",ksm(x,y,p));
}
else if(opt==2)
{
mp.clear();
long long aa,b,p;
int pd=0;
scanf("%lld%lld%lld",&aa,&b,&p);
if(b==1)
{
printf("0\n");
pd=1;
}
if(pd==1)
continue;
long long d=gcd(aa,p),t=1,k=0;
while(d!=1)
{
if(b%d)
{
printf("Math Error\n");
pd=1;
break;
}
++k;
b/=d;
p/=d;
t=(t*(aa/d))%p;
if(b==t)
{
printf("%lld\n",k);
pd=1;
break;
}
d=gcd(aa,p);
}
if(pd==1)
continue;
long long m=ceil(sqrt(p)),ans;
for(int j=0;j<=m;++j)
{
if(j==0)
{
ans=b%p;
mp[ans]=j;
continue;
}
ans=(ans*aa)%p;
mp[ans]=j;
}
long long x=ksm(aa,m,p);
ans=t;
for(int i=1;i<=m;++i)
{
ans=(ans*x)%p;
if(mp[ans])
{
x=i*m-mp[ans];
printf("%lld\n",x+k);
pd=1;
break;
}
}
if(!pd)
printf("Math Error\n");
}
else
{
long long x,y,mod;
scanf("%lld%lld%lld",&x,&y,&mod);
ji=mod;//mod就是CRT的那个因子乘积和!
if(mod==1)
{
printf("0\n");
continue;
}
memset(p,0,sizeof(p));
memset(a,0,sizeof(a));
int cnt=0;//记录质数个数
for(int i=2;i*i<=mod;++i)
{
if(mod%i==0)
{
p[++cnt]=1;
while(mod%i==0)
{
p[cnt]*=i;
mod/=i;//把当前因子除掉对看是否是后面数的倍数无影响
}
a[cnt]=exlucas(y,x,i,p[cnt]);
}
}
if(mod>1)
{
p[++cnt]=mod;
a[cnt]=exlucas(y,x,mod,mod);
}
long long res=0;
for(int i=1;i<=cnt;++i)
res=(res+a[i])%ji;
printf("%lld\n",res);
}
}
return 0;
}
常见模型和性质
奇偶性
- 当且仅当
n & m == m
时 \(C_n^m\) 为奇数
插板法
- n种元素,每种可选择任意次或者不选,共选m
\]
全错排公式
\]
情况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数学整理的更多相关文章
- NOIP数学相关模板整理
$O(n)$递推求逆元 #include<cstdio> #include<cstring> #include<algorithm> using namespace ...
- NOIP模板整理计划
先占个坑 [update]noip结束了,弃了 一.图论 1.单源最短路 洛谷P3371 (1)spfa 已加SLF优化 #include <iostream> #include < ...
- noip考点整理(应该不是很完整……)
部分来自百度百科.其他的博客 一.必须会的 1.暴力: DFS.BFS.灌水法搜索.回溯搜索.记忆化搜索.启发式搜索.最优性剪枝.可行性剪枝 2.贪心 3.模拟 4.骗分 二.基础算法 1.图论:SP ...
- NOIp 数学知识点总结
推荐阅读 NOIp 基础数论知识点总结: https://www.cnblogs.com/greyqz/p/number.html 排列组合 常用公式 排列:\[\displaystyle A_n^m ...
- $\rm{NOIp}$板子整理
怎么说呢,整理这个的目的就是为了有个简约的\(list\),方便以后查阅,复习起来不至于太吃力. 并且--好像重温一遍所有,会更有一些新的认识.这也算是对我所学的一点整理了吧. 一.并查集的两种方式 ...
- bzoj 3293 数学整理
和1045一模一样,找到这道题的时候还愣了下神,最后发现样例都是 一样的,直接粘了1045的代码,具体题解看 http://www.cnblogs.com/BLADEVIL/p/3468729.htm ...
- bzoj1257 数学整理二分查询
2013-11-15 21:55 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1257 要求求sigma k mod i(i<=n) ...
- 【模板】【学习笔记】noip数学
一.素数 欧拉筛 void prime(){ check[]=; ;i<=n;i++){ if(!check[i])prim[++cnt]=i;//这个if语句后面没有大括号!! ;j<= ...
- noip数学
一.取模运算 (1)定义 给定一个正整数p和一个整数n 一定存在此等式 n=k*p+r;其中k,r是整数,r大于等于0小于p 称k是n除以p的商,r为n除以p的余数 说明:同余式 正整数a,b对p取模 ...
随机推荐
- TypeScript 之 JSX
https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/JSX.html JSX中,类型断言必须使用as操作符. 类型检查 ...
- 浏览器多进程架构、浏览器内核多线程、js单线程、GUI 渲染线程 与 JavaScript引擎线程互斥 原理
浏览器是多进程的,有一个主控进程,以及每一个tab页面都会新开一个进程(某些情况下多个tab会合并进程). 出处:http://www.imweb.io/topic/58e3bfa845e5c1346 ...
- dockerfile创建php容器(安装memcached、redis、gd、xdebug扩展)
dockerfile创建php容器(含有memcached.redis.gd.xdebug扩展) 代码如下: FROM php:7.2-fpm COPY redis-3.1.6.tgz /home/r ...
- Springboot配置文件映射
添加类和配置文件的映射: 1.定义映射类 @Component @PropertySource("classpath:config/XX.properties") public c ...
- Linux VMware安装VMTools工具
安装VMTools工具 2)先启动CentOS并成功登录如下图,发现底部提示且窗口中等大小,准备安装 3)选择虚拟机菜单栏--安装VMware tools 4)光驱自动挂载VMTools 5)右键解压 ...
- 在Python中调用Java扩展包HanLP测试记录
最近在研究中文分词及自然语言相关的内容,关注到JAVA环境下的HanLP,HanLP是一个致力于向生产环境普及NLP技术的开源Java工具包,支持中文分词(N-最短路分词.CRF分词.索引分词.用户自 ...
- Eclipse提交代码到Spark集群上运行
Spark集群master节点: 192.168.168.200 Eclipse运行windows主机: 192.168.168.100 场景: 为了测试在Eclipse上开发的代码在Spa ...
- ML平台_PAI参考
阿里云机器学习PAI(Platform of Artificial Intelligence)是一款一站式的机器学习平台,包含数据预处理.特征工程.常规机器学习算法.深度学习框架.模型的评估以及预测这 ...
- URL中传递参数给视图函数
1. 采用在url中使用变量的方式: 在path的第一个参数中,使用<参数名>的方式可以传递参数.然后在视图函数中也要写一个参数,视图函数中的参数必须和url中的参数名称保持一致,不然就找 ...
- Winform 实现无边框窗体移动功能
#region 窗体移动 [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImp ...