noip_最后一遍_1-数学部分
它就是要来了
noip数论一般会以三种形式呈现
注 码风可能有些毒 (有人说我压行qwq) 大概保持标准三十五行左右
为什么是三十五行呢 因为我喜欢这个数字 我喜欢三十五而已(足球球衣也会用这个号哒)
1.结论规律与打表技巧
这类的题最杰出的代表是小凯的疑惑
打表技巧的话主要是研究三个要点
1.一个输入数据和模数时
oeis这个时候最好用了 不过没有
我们需要重点研究的是递推关系,差,二阶差这样
这时候我们会发现三类数据
· 等差等比二阶等差二阶等比等差等比………………这种都是有通项的 考验数学能力
· 与二进制和唯一分解定理有关
这个内容多 展开说
lowbit 1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5…………这个东西太常见了 不就是x&(-x)么 好的 可以开始考虑o n 数学方法比如化简Σ之类的
唯一分解定理目前我所见都很天然的 一眼就能看出来
二进制的1个数 这个东西是个阶梯状函数 所以也是比较容易找到规律的 至于如何统计 大概只能枚举位数
· 递推-这个时候就看一下数据 如果小或者递推关系复杂 就考虑dp与暴力枚举,否则上矩阵(一定要注意一下)
2.两到三个数据 没什么办法 直接找
3.一行数据(那其实是不等式和贪心)排序值 均值大概率在考纲之中 柯西的话我想没那么好出
本部分需要用的模板 所有代码最新手打测试无误可以使用
1.快速幂、快速乘
快速幂 :a^p-2=a^(-1)(modp);
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
ll n,k,x,a,b;
ll ksc(ll a,ll b,ll p){ll ans=,base=a;
for(;b;b>>=){if(b&)ans+=base,ans%=p;
base*=,base%p;
}return ans;
}
int main(){cin>>a>>b>>n;
cout<<ksc(a,b,n)<<endl;
}
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
ll n,k,x,a,b;
ll ksm(ll a,ll x,ll p){ll ans=,base=a;
for(;x;x>>=){if(x&)ans*=base,ans%=p;
base*=base,base%p;
}return ans;
}
int main(){cin>>a>>b>>n;
cout<<ksm(a,b,n)<<endl;
}
2.线性筛素数 phi mu
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 5000001
bool isprime[maxn];int n,m,sum=,prime[maxn];
void shai(){
for(int i=;i<maxn;i++){
if(!isprime[i])prime[sum++]=i;
for(int j=;j<sum&&i*prime[j]<maxn;j++){
isprime[i*prime[j]]=;if(i%prime[j]==)break;
}
}
}int main(){
cin>>n;shai();for(int i=;i<=n;i++)cout<<prime[i]<<" ";
}
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 5000001
bool isprime[maxn];int n,m,sum=,prime[maxn],phi[maxn];
void shai(){phi[]=,phi[]=;
for(int i=;i<maxn;i++){
if(!isprime[i])prime[sum++]=i,phi[i]=i-;
for(int j=;j<sum&&i*prime[j]<maxn;j++){
isprime[i*prime[j]]=;phi[i*prime[j]]=phi[i]*(prime[j]-);
if(i%prime[j]==){phi[i*prime[j]]=phi[i]*prime[j];break;}
}
}
}int main(){
cin>>n;shai();for(int i=;i<=n;i++)cout<<phi[i]<<" ";
}
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 5000001
bool isprime[maxn];int n,m,sum=,prime[maxn],phi[maxn],mu[maxn];
void shai(){phi[]=,phi[]=;mu[]=;
for(int i=;i<maxn;i++){
if(!isprime[i])prime[sum++]=i,phi[i]=i-,mu[i]=-;
for(int j=;j<sum&&i*prime[j]<maxn;j++){
isprime[i*prime[j]]=;phi[i*prime[j]]=phi[i]*(prime[j]-);mu[i*prime[j]]=-mu[i];
if(i%prime[j]==){phi[i*prime[j]]=phi[i]*prime[j],mu[i*prime[j]]=;break;}
}
}
}int main(){
cin>>n;shai();for(int i=;i<=n;i++)cout<<mu[i]<<" ";
}
3.数论分块 这是个技巧……
4.矩阵快速幂
这个有点烦的是一直dev调试这个会出大问题 好像就是dev5.4.2的bug一样
他在调试时会自己死机 一会又好了 有时候烦的一批 鬼使一样
并且奇特的是新建矩阵居然不会自动清空这就很奇特
可能是个大bug 5.4.2的版本会出这个问题 考试时候可能是5.4.2 所以说解决办法就只有一个 一遍打对,每次新建memset
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 105
#define mod 1000000007
struct matrix{ll a[maxn][maxn],len,row;}m1;ll n,m,k,l;
matrix jc(matrix a,matrix b){
matrix now;now.len=b.len,now.row=a.row;memset(now.a,,sizeof(now.a));
for(int i=;i<=a.row;i++){
for(int j=;j<=b.len;j++){
for(int k=;k<=a.len;k++){
now.a[i][j]+=a.a[i][k]*b.a[k][j],now.a[i][j]%=mod;
}
}
}return now;
}matrix ksm(matrix a,ll x){
matrix base=a,ans;ans.len=a.len,ans.row=a.row;memset(ans.a,,sizeof(ans.a));
for(int i=;i<=a.len;i++)ans.a[i][i]=;
for(;x;x>>=){
if(x&)ans=jc(ans,base);
base=jc(base,base);
}return ans; }
int main(){cin>>n>>k;m1.len=m1.row=n;
for(int i=;i<=n;i++)for(int j=;j<=n;j++)cin>>m1.a[i][j];
m1=ksm(m1,k);
for(int i=;i<=n;i++){for(int j=;j<=n;j++)cout<<m1.a[i][j]<<" ";
cout<<endl;}return ;
}
5.二进制 这也是技巧 没有代码
这一类题大概也就这样 真的出来了什么鬼题也没办法
2.正宗数论
其实有意思的一匹 很有意思
1.带余除法为核心
·逆元线性递推
设 t=ki+b;求t^(-1)
图片出处-guessycb暗中给了我许多 十分感谢
#include<iostream>
using namespace std;
#define maxn 5000005
#define ll long long
ll n,m,p,f[maxn];
int main(){cin>>n>>p;
f[]=;for(int i=;i<=n;i++){
f[i]=(p-p/i)*f[p%i]%p;
}for(int i=;i<=n;i++)printf("%lld\n",f[i]);
}
2.唯一分解定理为核心 这个都知道就是什么因子和因子个数 有的时候你以为很暴力 不过由于那个基本时间复杂度定理 它是跟n的或者log的或者on的
3.exgcd为核心
这个大概有两类出法 1.青蛙的约会——荒野猎人 这两个基本是必做题吧 ab可不互质啊
求同余方程解 a=b(modc)->ax+cy=b; (a,c)=d;
有ax0+cy0=1 x=(x0*(b/d)+p)%p*c 此处p为x取值周期
第二类 关于gcd、lcm 那个乘积代换式一定不会单独考 因为太low
gcd这个物质它不但可以与exgcd建立莫大的联系 还可以维系phi mu 莫比乌斯反演 那种东西其实很套路 有趣的一匹
跟exgcd的时候 我们熟知 m(a,b)=(ma,mb)=m(a+b,b)这样就是他 还真有这么几道题
4.crt 一张图
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 1000005
ll n,m[maxn],l,a[maxn],t[maxn],M=,k[maxn],ans=;
void exgcd(ll a,ll b,ll &x,ll &y){
if(!b){x=,y=;return ;}
exgcd(b,a%b,y,x);y-=a/b*x;
}
ll qpow(ll a,ll x,ll p){ll ans=,base=a;
for(;x;x>>=){
if(x&)ans=ans*base%p;
base=base*base%p;
}return ans;
}
int main(){
cin>>n;
for(int i=;i<=n;i++)cin>>a[i]>>m[i],M*=m[i];
for(int i=;i<=n;i++){t[i]=M/m[i];exgcd(t[i],m[i],k[i],l);
k[i]=(k[i]%m[i]+m[i])%m[i];
ans=(ans+a[i]*t[i]*k[i])%M;
}cout<<ans<<endl;
}
5.卢卡斯 它的本质是模数意义下的c 配合crt求出原始值(古代猪文)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define maxn 300005
ll f[maxn],inv[maxn],n,m,k,p;
ll qpow(ll a,ll x,ll p){ll ans=,base=a;
for(;x;x>>=){
if(x&)ans=ans*base%p;base=base*base%p;
}return ans;
}
ll c(ll n,ll m,ll p){if(m<n)return ;
ll a=qpow(f[n],p-,p),b=qpow(f[m-n],p-,p);
return f[m]*a*b%p;
}
ll lucas(ll n,ll m,ll p){
if(!n)return ;
return c(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
int main(){cin>>k;
while(k--){
cin>>n>>m>>p,f[]=;
for(int i=;i<maxn;i++)f[i]=f[i-]*i%p;
cout<<lucas(n,n+m,p)<<endl;
}
}
6.欧拉定理和马小
有个题叫a^b^c%p
这个东西怎么求呢 就是欧拉定理 a^b=a^((b%phi[p])+phi[p])(modp)但是需要特判
(1)当n>1,(a,n)=1时, a^b%n=a^b%φ(n)%n
(2)当b≤φ(n)时,直接计算即可。
(3)当b>φ(n)时 , 刚才的式子
7.phi的用法
几个零碎的点
·观察者问题
·互质对 这个说一下 求Σ(1-n)Σ(1-m)【gcd(i,j)==1】是那个莫反套路
刻意背过也可以 ∑ i=1-n∑ j=1-m [gcd(i,j)=1] =∑ i=1-n μ(i) ⌊n/i⌋∗⌊m/i⌋
如果把第二个m变成n就大不一样了
对于1每个n(1-n)与他互质且比他小(避免算重)的个数就是phi【i】
·母函数与二项式定理
考过二项式定理裸题 母函数的话主要是求 一个奇怪的组合数 然后对函数加减
不过noip不太会考它
3.几何和组合
数学的话还要看一手几何和组合数学
有点相同 所以一起看一手
组合——几个方法
·隔板法 要求划分出非空k集 =c(k,n+1)有空集一样 等于每个集合多个元素罢了
·折线法 其实是组合和坐标的加和
(1,1)-》(n,m)方案=c(n,n+m);
然后 我们考虑一种到达目标点且不经过固定几何图形的方案数
其实就是容斥,目标点关于几何图形对称 方案数就是相减
·高级容斥 想清楚要求什么 什么好求
几何
·矢量叉积-求面积 夹角
·矢量旋转
已知任意一个平面向量ab=(x,y) ,把向量ab绕其起点沿逆时针方向旋转a角得到向量AP=(xcosa-ysina,xsina+ycosa)
一堆操作 在这个板子里 还有就是旋转九十度什么的就直接搞点就行 向量用不着
#include<bits/stdc++.h>
using namespace std;
int n;double ans,m;
struct node{double x,y;}a[];
node add(node a,node b){node c;c.x=a.x+b.x,c.y=a.y+b.y;return c;}//+
node niadd(node a,node b){node c;c.x=a.x-b.x,c.y=a.y-b.y;return c;}//- double dot(node a,node b){return a.x*b.x+a.y*b.y;}//·
double cha(node a,node b){return a.x*b.y-a.y*b.x;}//* double len(node a){return sqrt(a.x*a.x+a.y*a.y);}// |a|
double squ(){ // S
for(int i=;i<n;i++)ans+=(double)cha(a[i],a[i+])/;
ans+=(double)cha(a[n],a[])/;
return fabs(ans);
}
double geta(node a,node b){//获得小夹角cos值
return dot(a,b)/(len(a)*len(b));
}
node rotate(node a,double coss){//旋转arccosa度(正向)(逆时针)
double sins=sqrt(-coss*coss);
node c;c.x=a.x*coss-a.y*sins,c.y=a.x*sins+a.y*coss;
return c;
}
double angle(double cosa){
return acos(cosa);
} node adjust(node a,double b){
a.x*=b/len(a),a.y*=b/len(a);return a;
}
int main(){
cin>>n>>m;for(int i=;i<=n;i++)cin>>a[i].x>>a[i].y;
printf("%.4f\n",squ()*(double)m);
}
·凸包
这个真的捞 因为手打队列具有无比的优势 就是他需要访问栈顶第二个元素 求出上凸壳然后怎么办呢 noip的话大概二分y轴会有机会考吧
还有就是凸包可以做直线的相交问题
尤其是相交+极值。
上几个板子
1.洛谷模板 叉积判断夹角正负
#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 ;
}
2.板子中的板子[HNOI2008]水平可见直线
#include<bits/stdc++.h>
using namespace std;
#define maxn 50005
#define ll long long
ll n,m,k,a,b,c,s[maxn],top=,ans[maxn];
struct node{int k,b,id;}l[maxn];
bool cmp(node a,node b){
return a.k==b.k?a.b>b.b:a.k<b.k;
}double getx(int a,int b){
return (double)(l[a].b-l[b].b)/(double)(l[a].k-l[b].k);
}
int main(){
cin>>n;for(int i=;i<=n;i++)cin>>l[i].k>>l[i].b,l[i].id=i;
sort(l+,l+n+,cmp);
for(int i=;i<=n;i++){
if(l[i].k==l[i-].k&&i!=)continue;
while(top>&&getx(s[top],i)>=getx(s[top],s[top-]))top--;
s[++top]=i;
ans[top]=l[i].id;
}sort(ans,ans+top+);
for(int i=;i<=top;i++)printf("%d ",ans[i]);
}
·三分
noip很可能在考纲里因为它就是二分的翻版。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,k;double a[],l,r;
double f(double pos){double ans=;
for(int i=;i<=n+;i++){
ans+=pow(pos,n-i+)*a[i];
}return ans;
}
double sanfen(double l,double r){
if(r-l<0.000001)return l;
double mid1=l+(r-l)/,mid2=r-(r-l)/;
if(f(mid1)>f(mid2))return sanfen(l,mid2);
else return sanfen(mid1,r);
}
int main(){
cin>>n>>l>>r;
for(int i=;i<=n+;i++)cin>>a[i];
printf("%.5f",sanfen(l,r));
}
4.其他
细数了一下其实剩下的只有俩——高斯消元与行列式和线型基 要是考什么bsgs 就很烦了 不过bsgs还是看一看最好
另外什么牛顿迭代 matrixtree之类的谁知道他会不会灵性来一下 都发下
高消(行列式矩阵树都是对对角线矩阵求积)构造矩阵自己查吧 这个好像不属于板子(逃)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vecotr>
#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 ;
}
牛顿迭代求高次开跟
#include<bits/stdc++.h>
#define first 233.0
#define ll long long
#define ld double
ld n,m,k,l,a,b,c,x;
using namespace std;
ll ksm(ll a,ll x){ll base=a,ans=;
for(;x;x>>=){
if(x&)ans=base*ans;
base=base*base;
}
return ans;
}
int main(){
cin>>a>>m;x=first;
for(int i=;i<=;i++)x=x-x/m+a/((ld)*m*ksm(x,m-));
cout<<x<<endl;
}
线型基
这个东西只有一种用处 求最大异或和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 105
ll n,m,k=,l,s[maxn],a[maxn];
void insert(ll x){
for(int i=;i>=;i--){if(!x)return ;
if((x&(1ll<<i))!=){
if(!s[i])s[i]=x;
x^=s[i];
}
}
}
int main(){
cin>>n;for(int i=;i<=n;i++)cin>>a[i],insert(a[i]);
for(int i=;i>=;i--)if((k^s[i])>k)k^=s[i];
cout<<k<<endl;return ;
}
那么数论基本结束了
高斯消元是薄弱点 第二次争取全对(其实有错更好)
祝rp++ 高分预定!!!
noip_最后一遍_1-数学部分的更多相关文章
- noip_最后一遍_2-图论部分
大体按照 数学 图论 dp 数据结构 这样的顺序 模板集 这个真的只有模板了……………… ·spfa #include<bits/stdc++.h> using namespace std ...
- noip_最后一遍_3-数据结构
noip基础数据结构太多了又太捞了 所以也就那么几个了 单调队列滑动窗口 #include<bits/stdc++.h> using namespace std; #define maxn ...
- 最近关于ACM训练与算法的总结
到了大四以后越来越意识到基础知识的重要性,很多高屋建瓴的观点与想法都是建立在坚实的基础之上的, 招式只有在强劲的内力下才能发挥最大的作用,曾经有段时间我有这样的想法:我们出去以后和其他 ...
- PAT 1049 Counting Ones[dp][难]
1049 Counting Ones (30)(30 分) The task is simple: given any positive integer N, you are supposed to ...
- 5天突击GRE(155+170+4.0)
个人认为最靠谱GRE经验,没有之一 虽然分数并不高(V 155 + Q 170 + AW 4.0),但是自认为有很多很多可以拿来给短期突击同学的宝贵经验. 首先是自己的背景,交大英语教改实验班(交大同 ...
- 一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)
转自:http://www.math.org.cn/forum.php?mod=viewthread&tid=14819&extra=&page=1 原作者: wcboy 现在 ...
- [中英双语] 数学缩写列表 (List of mathematical abbreviations)
List of mathematical abbreviations From Wikipedia, the free encyclopedia 数学缩写列表 维基百科,自由的百科全书 This ar ...
- 3D数学 ---- 矩阵和线性变换[转载]
http://blog.sina.com.cn/s/blog_536e0eaa0100jn7c.html 一般来说,方阵能描述任意线性变换.线性变换保留了直线和平行线,但原点没有移动.线性变换保留直线 ...
- [家里蹲大学数学杂志]第033期稳态可压Navier-Stokes方程弱解的存在性
1. 方程 考虑 $\bbR^3$ 中有界区域 $\Omega$ 上如下的稳态流动: $$\bee\label{eq} \left\{\ba{ll} \Div(\varrho\bbu)=0,\\ \ ...
随机推荐
- [Xcode 实际操作]八、网络与多线程-(10)使用异步Get方式查询GitHub数据
目录:[Swift]Xcode实际操作 本文将演示如何通过Get请求方式,异步获取GitHub资源的详细信息. 异步请求与同步请求相比,不会阻塞程序的主线程,而会建立一个新的线程. 在项目导航区,打开 ...
- 17..userinfo.txt 文件中存放以下结构:
alex:alex3714 wusir:123456 meet:meet123 1.让用户选择: 1.注册 2.登录 2.用户选择注册就将账号和密码添加到userinfo.txt中,如果用户名存在就提 ...
- java并发编程(一)
java并发编程(一) 线程基础 在Java代码中,单独创建线程,都需要使用类java.lang.Thread,通常可以通过集成并扩展Thread的run()方法,也可以来创建一个Thread,将一个 ...
- 5 天 4000 star 的一个爆款开源项目
今天早上起来浏览 GitHub 的时候,在周热门趋势排行榜上看到了这么一个开源项目,仅仅 5 天时间,爬到了周排行榜的第一名的位置.而在每天的排行榜上,今天一早也高高位居排行榜的第二位. 这个开源项目 ...
- 黑马Stream流学习 Stream流 函数式接口 Lambda表达式 方法引用
- MyBatis逆向工程中domainObjectRenamingRule报错或无效
使用domainObjectRenamingRule报错 在使用MyBatis逆向工程时报错如下: org.mybatis.generator.exception.XMLParserException ...
- insert后面value可控的盲注(第一次代码审计出漏洞)
这个叫诗龙的cms真的很感谢他的编写人,全站注入~~一些特别白痴的就不说了,这里有一个相对有点意思的 很明显的注入,然后去直接利用报错注入想爆出数据结果发现没有开报错模式. 报错注入http://ww ...
- AKOJ-1265-输出二叉树
链接:https://oj.ahstu.cc/JudgeOnline/problem.php?id=1265 题意: 我们知道二叉树的先序序列和中序序列或者是中序和后序能够唯一确定一颗二叉树.现在给一 ...
- asp.net core分块上传文件
写完asp.net多文件上传(http://www.cnblogs.com/bestckk/p/5987383.html)后,感觉这种上传还是有很多缺陷,于是...(省略一万字,不废话).这里我没用传 ...
- python语法:
1 #开始注释,‘’‘ ‘’’可以看做是文本字符串也可以看做是块注释:”:“开始后的缩进视为一个代码块类似{}:缩进没有规定,但一般4个空格,注意:粘贴复制代码一定要检查缩进:大小写敏感: 2 数据 ...