NOIP复习之1 数学数论
noip一轮复习真的要开始啦!!!
大概顺序是这样的
1.数学
2.搜索贪心
3.数据结构
4.图论
5.dp
6.其他
数学
1.数论
数论被称为数学皇冠上的明珠,他的重要性主要在于它是其他学习的祖师,基本上什么代数问题都可以通过数论推导,其实有的图论也是(数学上)。
我们信息中的数论主要是说对整除同余的研究~~~~~~~
①:唯一分解定理与素数
这个之前我们先要讲素数(定义全部掠过)
素数筛法:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int prime[],phi[],n,m,k,l,a,b;
bool isprime[];
void shai()
{
int sum=;
memset(isprime,,sizeof(isprime));
memset(prime,,sizeof(prime));
for(int i=;i<=n;i++)
{
if(!isprime[i])
{
prime[sum++]=i;
phi[i]=i-;
}
for(int j=;j<sum&&prime[j]*i<=n;j++)
{
isprime[prime[j]*i]=;
if(i%prime[j]==)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else
{
phi[i*prime[j]]=phi[i]*(prime[j]-);
}
}
}
}
int main()
{
phi[]=;
cin>>n;
shai();
for(int i=;i<=n;i++)
cout<<phi[i]<<" ";
return ;
}
这里面也有一个叫phi的东西。。。我们一会再说。
筛好以后我们就可以根绝唯一分解定理分解素数
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int prime[],phi[],cut[][],num=,n,m,k,l,a,b;
bool isprime[];
void shai()
{
int sum=;
memset(isprime,,sizeof(isprime));
memset(prime,,sizeof(prime));
for(int i=;i<=;i++)
{
if(!isprime[i])
{
prime[sum++]=i;
phi[i]=i-;
}
for(int j=;j<sum&&prime[j]*i<=n;j++)
{
isprime[prime[j]*i]=;
if(i%prime[j]==)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else
{
phi[i*prime[j]]=phi[i]*(prime[j]-);
}
}
}
}
int main()
{
phi[]=;
shai();
cin>>m;
for(int i=;i<=;i++){
if(m==)break;
while(m%prime[i]==)m/=prime[i],cut[i][]=prime[i],cut[i][]++;
}
for(int i=;i<=;i++){
if(cut[i][]!=)
cout<<cut[i][]<<" "<<cut[i][]<<endl;
}
return ;
}
省选之后我们发现o跟下n求一个数的唯一分解是不够的
于是就有了miller rabin。
这个东西是根据那个费马小定理(欧拉定理)的p为素数的条件进行的素数测试。
这个东西有个兄弟叫rho
这个东西是用来解决找合数因子的
把主程序里的不断除m改为知道miler检测到为素数为止。
好了那么我们就可以对10^18次方之内的进行分解了(noip只会考on)
那么有什么用呢?
我们把分解后的表示为π(ai^pi)
1.因子数:π(pi+1);
2.因子和:这个很有意思:
ans=(1+p1^1+p1^2+......+p1^a1)(1+p2^1+p2^2+......+p2^a2)(1+p3^1+p3^2+......+p3^a3)......(1+pn^1+pn^2+......+pn^an)
=π(1-pi^ai)/(1-pi);
这个东西逆元就行。
②快速幂(模数的最广泛应用(二进制))
//ksm
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<fstream>
#include<cstring>
using namespace std;
#define ll long long
ll qpow(ll a,ll x)
{
ll base=a,ans=;
for(;x>;x>>=)//简单办法
{if(x&)
ans*=base;//当为奇数叠加求解
base*=base;
}
return ans;
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".in","r",stdin);
ll a,b;
cin>>a>>b;
cout<<qpow(a,b);
return ;
}
这个东西根据费马小定理可以求逆元
方法是a^(mod-2)=a^(-1)mod mod;
快速乘其实是龟速乘
利用二进制实现调整中途溢出long long的膜意义下乘法
也是利用二进制表示
这样就可解决10^18次方的两个数在%意义下的乘法取模
(其实它是log length的复杂度,并不快,只是比n个相加取模要快(传统防止溢出)所以不是像noi2018龙和勇士那种问题不要乱用)
#include<iostream>
#define mod 1000000007
#define ll long long
using namespace std;
ll ksc(ll a,ll b){
ll ans=,base=a;
for(;b;b>>=){
if(b&)ans=(ans+base)%mod;
base=base*%mod;
}
return ans;
}
ll a,b;
int main(){
cin>>a>>b;
cout<<ksc(a,b);
return ;
}
③exgcd gcd
gcd太熟悉了现打一个
long long gcd(long long a,long long b){
return !b?a:gcd(b,a%b);
}
exgcd也差不多 exgcd也可以求逆元的,这个定义式推。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int gcd(int a,int b)
{
return b==?a:gcd(b,a%b);
}
void exgcd(int a,int b,int &d,int &x,int &y)
{
if(!b){d=a;x=;y=;return ;}
exgcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
int main ()
{
int m,n,k;
cin>>m>>n>>k;
int gc=gcd(n,m);
m/=gc;n/=gc;
k/=gc;
int x,y,d;
cout<<m<<"x+"<<n<<"y="<<gc<<endl;
exgcd(m,n,d,x,y);
cout<<x<<" "<<y<<endl<<d<<endl<<endl;
for(int i=;i<=;i++)
{
x+=(n)*i;
y-=(m)*i;
cout<<x<<" "<<y<<endl;
}
return ;
}
④excrt。crt
excrt 在noip是在不大可能考,要考也是t3的最后一部分,毕竟noi t1难度不是盖的(当时本蒟蒻只拿了三十分那个题。。。。)
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstdio>
#include<cstring>
using namespace std;
long long m[],ma[],a[],c,mall=,ansx;
long long qpowmod(long long a,long long x,long long p)
{
long long base=a,ans=;
for(;x>;x>>=){
if(x&)
ans*=base,ans%=p;
base*=base,base%=p;
}
return ans%p;
}
int main()
{ cin>>c;
for(int i=;i<=c;i++){
cin>>a[i]>>m[i];
mall*=m[i];
}
for(int i=;i<=c;i++){
ma[i]=mall/m[i];
}
for(int i=;i<=c;i++){
ansx+=a[i]*ma[i]*qpowmod(ma[i],m[i]-,mall);
ansx%=mall;
} cout<<mall<<endl<<ansx<<endl;
}
excrt的话就是加一个exgcd就行。
另外 我们需要利用bezout解决问题比如小凯的疑惑
几个简单而熟知的结论
(a,b)=(a+b,b)=(a-b,b)
ax+by=(a,b) x,y∈z
2.计算几何
计算几何noip要是考也是向量题,最多带个凸包。
①向量点积a2b1-a1b2
②凸包:这个东西在斜率优化那里有(那里是个上凸壳),大概是完全一样的。栈维护进出
保证点积>0
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
struct node{
double x,y;
}p[],s[];
int n;
double ans,mid;
double CJ(node a1,node a2,node b1,node b2)
{
return (a2.x-a1.x)*(b2.y-b1.y)-(b2.x-b1.x)*(a2.y-a1.y);
}
double dis(node p1,node p2)
{
return sqrt( (double)(p2.y-p1.y)*(p2.y-p1.y)*1.0+(double)(p2.x-p1.x)*(p2.x-p1.x)*1.0 );
}
bool cmp(node p1,node p2)
{
double tmp=CJ(p[],p1,p[],p2);
if(tmp>) return ;
if(tmp== && dis(p[],p1)<dis(p[],p2)) return ;
return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
if(i!=&&p[i].y<p[].y)
{
mid=p[].y;p[].y=p[i].y;p[i].y=mid;
mid=p[].x;p[].x=p[i].x;p[i].x=mid;
}
} sort(p+,p++n,cmp);
s[]=p[];
int tot=;
for(int i=;i<=n;i++)
{
while(tot>&&CJ(s[tot-],s[tot],s[tot],p[i])<=) tot--;
tot++;
s[tot]=p[i];
}
s[tot+]=p[];
for(int i=;i<=tot;i++) ans+=dis(s[i],s[i+]);
printf("%.2lf\n",ans);
return ;
}
3.递推,矩阵初步与数列
①几个有趣的特殊数列
②ologn求通项的几(两)种方法(noipt2t3){
1.特征根
这个东西没有任何代码。。。就是求数列通项。
通过特征方程解出跟
然后带a1,a2,a3……an进去
可以看看这个
https://wenku.baidu.com/view/6e270e87284ac850ac024203.html
2.矩阵快速幂
这个十分好理解(在矩阵乘法理解的基础上)我们可以认为数列是一个行向量
而一个n阶递推数列对应一个列向量,所以因此我们就需要找到一个由前一个列向量递推到下一个的矩阵。
这个矩阵可以记一个结论
它是 对于n阶矩阵 ai为系数
n*n大小
[a1,a2,a3,a4,……,an]
[10000000000……00]
[010000000……00]
[0010000000……00]
[00010000000……00]
[000010000000……00]
.
.
[0………………1]
然后 矩阵快速幂!!!
就是矩阵乘法代替那个快速幂的乘就行
代码!!!
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,k;
struct mix{
int a[][];
};
mix mx (mix a1,mix a2,int n)
{
mix a3;int ans=;
memset(a3.a,,sizeof(a3.a));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
ans=;
for(int k=;k<=n;k++)
{
ans+=a1.a[i][k]*a2.a[k][j];
}
a3.a[i][j]=ans;
}
return a3;
}
mix ksm(mix a,int x)
{
mix ans;
memset(ans.a,,sizeof(ans.a));
for(int i=;i<=n;i++)
ans.a[i][i]=;
for(;x;x>>=)
{
if(x&)
mx(ans,a,n);
mx(a,a,n);
}
return ans;
}
int main()
{
mix m1;
cin>>n>>k;
cout<<endl<<n<<endl<<k;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
cin>>m1.a[i][j]; mix m=ksm(m1,k);
for(int i=;i<=n;i++)
{
cout<<endl;
for(int j=;j<=n;j++)
{
cout<<m.a[i][j]<<" ";
}
}
cout<<endl<<n<<endl<<n;
return ;
}
}
③关于高斯消元基础(noip不会考于t1t2){
这个模板是用来解决n阶定方程的
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 100
using namespace std;
int n,m,k,l,a,b,c;double mp[maxn][maxn];
int main(){
cin >> n;
for(int i = ; i <= n; i ++)
for(int j = ; j <= n + ; j ++)
cin >> mp[i][j];
for(int j = ; j <= n; j ++){
int rgt = ;
for(int i = j; i <= n; i ++)
if(mp[i][j]){rgt = i; break;}
if(!rgt)continue;
if(rgt ^ j)swap(mp[rgt],mp[j]); for(int i = j + ; i <= n; i ++){
double div = mp[i][j] / mp[j][j];
for(int k = ; k <= n + ; k ++)mp[i][k] -= div*mp[j][k];
}
}
for(int j = n; j >= ; j --){
if(mp[j][j] == ){cout<<"No Solution"; return ;}
mp[j][n+] = mp[j][n+] / mp[j][j];
for(int i = j-; i >= ; i --)mp[i][n+] -= mp[j][n+] * mp[i][j];
}
for(int i = ; i <= n; i ++)printf("%.2lf\n" ,mp[i][n+]);
return ;
}
高斯消元还可以解决一些异或,异或这个东西跟加法很相似。
因为若 a+(1<<k)&&(a>>k)&1==0 这个时候更加一样,否则就是减。
我们发现高斯消元是on^3的,那么如果让跑1000之内的怎么办呢。
我们就需要一个玄学的东西叫做线型基!
这个东西是一个纯粹的省选算法,noip向了解即可。
}
④基本数列公式
{
1.等比数列求和
2.等差数列求和
3.等差数列性质
}
题目
1.P3938 斐波那契
2.P1306 斐波那契公约数
3.P1962 斐波那契数列
4.P1939 【模板】矩阵加速(数列)
4.函数(积性函数初步)
①三分法{
用于求单峰函数的极值
我们发现如果取两个点(三分之一位置)mid1 mid2
会有三种情况(还有一种是相等,那时候任意都行)
mid1>mid2那么峰值不可能在mid2-r;
mid1<mid2峰值不可能在 l-mid1;
那么我们就会发现递推即可缩小lr
锁定峰值
洛谷搜索三分法有模板
// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#define maxn 1000
using namespace std;
double n,m,a,b,mid1,mid2,k[maxn];
double f(double x){
double ans;
ans=k[];
for(int i=;i<=n;i++){
ans+=pow(x,i)*k[i];
}
return ans;
}
double sanfen(double l,double r){
if(r-l<0.000001)return l;
double mid1=(r-l)/+l;
double mid2=r-(r-l)/;
//cout<<f(mid1)<<" "<<f(mid2)<<endl;
if(f(mid1)>f(mid2))r=mid2;
else l=mid1;
return sanfen(l,r);
}
int main(){
cin>>n>>a>>b; for(int i=n;i>=;i--){
cin>>k[i];
}//cout<<f(a)<<" "<<f(b)<<endl;
printf("%.5lf",sanfen(a,b));
return ;
}
这个东西还可以处理凸壳(见计算几何)
}
② 欧拉函数
我在前面写了筛法,自己回去找吧
有用的性质(莫比乌斯反演证明出来的)(Σ(d|n)φ(d))=n
中间的竖杠,整除的意思。
③莫比乌斯反演初步——这个noip如果考了 ccf就是疯了,真的!!!!!
做题可以看一个叫popoqqq的人的博客最底下。
5.概率论
考过 不难 没啥好总结的 主要是推式子 那就结束吧
省选数学有哪些内容呢?
哎,加油吧!
一维数学
exgcd,crt,excrt,gcd,bsgs,exbsgs,快速幂,龟速乘,哈希,MillerRabin,Ruben rho,线性筛积性函数,素数线性筛,欧拉公式,费马小定理,乘法逆元,欧拉函数优化快速幂,拉格朗日查值,莫比乌斯反演,fft/ntt,杜教筛,高斯函数化简,牛顿迭代,泰勒展开。
计算几何
凸包,半平面交,旋转卡壳,三分法,导数,定积分分析时间复杂度
组合数学(二维数学)
卢卡斯定理,拓展卢卡斯,matrixtree,高斯消元,异或方程,线性基,行列式求值,矩阵乘法,矩乘快速幂,递推数列特征根
NOIP复习之1 数学数论的更多相关文章
- NOIP复习篇
NOIP复习篇---枚举 --------------------------------------------------------------------------------------- ...
- NOIP考前复习-数制转换,数论模板与文件读写
数制转换有两种题型,一般一题,分值1.5分. 题型一:R进制转十进制 解法就是:按权展开,但要注意各个位的权,最低位(最右边)的权是0次方,权值为1. 纯整数的情况: (11010110)2 = 1× ...
- 冲刺NOIP复习,算法知识点总结
前言 离NOIP还有一个星期,匆忙的把整理的算法补充完善,看着当时的整理觉得那时还年少.第二页贴了几张从贴吧里找来的图片,看着就很热血的.当年来学这个竞赛就是为了兴趣,感受计算机之美的. ...
- [Noip复习知识点][个人向]Zackzh
只是列列一些要复习的,努力复习吧,有种noip退役的赶脚. 一.模拟 (这你也不会?退役吧) 二.DP 1.基础dp 2.区间dp 3.状压dp 4.树形dp 6.概率(期望)dp 7.环形dp 8. ...
- Noip前的大抱佛脚----数论
目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...
- 具体数学数论章-----致敬Kunth
整除性(divisible): 引入了代表整除性. m\n (m|n) 表示m整除n.注意这里的整除.表示的是n = km(k为整数). 在整除性这里.m必须是个正数.也许你可以描述n 是 m 的k倍 ...
- [NOIP复习]第三章:动态规划
一.背包问题 最基础的一类动规问题.相似之处在于给n个物品或无穷多物品或不同种类的物品,每种物品仅仅有一个或若干个,给一个背包装入这些物品,要求在不超出背包容量的范围内,使得获得的价值或占用体积尽可能 ...
- 【NOIP复习】最短路总结
[模板] /*堆优化Dijkstra*/ void dijkstra() { priority_queue<pair<ll,int>,vector<pair<ll,int ...
- 数学--数论--HDU - 6395 Let us define a sequence as below 分段矩阵快速幂
Your job is simple, for each task, you should output Fn module 109+7. Input The first line has only ...
随机推荐
- PHP composer 日常使用命令和理解
composer的操作很多很杂,平时大都用不上,正要找又一时半会难找到 日常操作,走起 第一部分 : 安装 composer.json composer init 这个命令创建了一个 composer ...
- BZOJ 4236: JOIOJI map瞎搞
分别记录J,O,I,的个数 cnt[char][i] 表示处理到第i位,char的个数 显然当且仅当 cnt[J][i] - cnt[O][i] == cnt[J][j-1] - cnt[O][j-1 ...
- 洛谷1373(dp)
常规线性dp,需要时就加一维.\(dp[i][j][t][s]\)表示在点\((i,j)\)时瓶子里剩\(t\)且为\(s\)走(0代表小a,1代表uim)时的方案数. de了半天发现是初次尝试的快速 ...
- P1101 单词方阵(DFS)
题目描述 给一n \times nn×n的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88个方向的任一方向,同一单词摆放时不再 ...
- 无线网路由器的dBm值
首先,我们需要知道的是无线信号 dbm都是负数,最大是0:dbm值只在一种情况下为0,那就是在理想状态下经过实验测量的结果,一般我们认为 dbm为0是其最大值,意味着接收方把发射方发射的所有无线信号都 ...
- D. Array Division
http://codeforces.com/contest/808/problem/D 一开始是没什么想法的,然后回顾下自己想题的思路,慢慢就想出来了.首先要找到是否有这样的一个位置使得: 前缀和 = ...
- 《springcloud 一》搭建注册中心,服务提供者,服务消费者
注册中心环境搭建 Maven依赖信息 <parent> <groupId>org.springframework.boot</groupId> <artifa ...
- 《四 spring源码》利用TransactionManager手写spring的aop
事务控制分类 编程式事务控制 自己手动控制事务,就叫做编程式事务控制. Jdbc代码: Conn.setAutoCommite(false); // 设置手动控制事务 Hibern ...
- java实现xml文件读取并保存到对象
首先浅聊一下解析xml的四种方式: 1.DOM方式:有缺点但是这个缺点却也是他的优点.下面详细介绍: 以树形的层次结构组织节点或信息片断集合,可以获得同一个文档中的多处不同数据.使用起来简单. 优点是 ...
- 自动生成sql
添加下面这个类 public static class GetAllAttribute<T> where T : class { public static string Names; p ...