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 实际操作]七、文件与数据-(23)UI Testing系统界面测试功能的使用
目录:[Swift]Xcode实际操作 本文将演示UI Testing系统界面测试功能的使用. 如果项目中尚未引入界面测试功能,请点击项目属性面板->[General]面板左下角的[+]图标 - ...
- Mol Cell Proteomics. |陈洁| 整合鸟枪法蛋白质组学中鉴定和定量的错误率
大家好,本周分享的是发表在MCP上的一篇关于鸟枪蛋白质组学中的错误率的文章,题目是Integrated identification and quantification error probabil ...
- log4j2中LevelRangeFilter的注意点
LevelRangeFilter的注意点 在log4j2中,LevelRangeFilter的minLevel,maxLevel的配置是和log4j 1.x相反的:minLevel需要配置的是高级别, ...
- mysql整理(个人)
注意:以下命令都是在Linux系统下执行的: 1.验证mysql是否安装成功: mysqladmin --version 2.连接mysql服务器: mysql -u root -p 之后输入密码 3 ...
- “玲珑杯”ACM比赛 Round #4 E -- array DP
http://www.ifrog.cc/acm/problem/1050?contest=1006&no=4 DP[val]表示以val这个值结尾的等差数列有多少个 DP[val] += DP ...
- TDH-search常用命令
一.指令部分:1.search管理界面地址: http://172.20.230.110:9200/_plugin/head/ 2.集群状态查看命令: curl -XGET 'localhost:92 ...
- Redis的发布和订阅
Redis的发布和订阅 Redis发布订阅(pub/sub)是一种消息通信模式,pub发布消息,sub接收消息.(pub/sub)是一种生产者消费者模式,是实现消息队列的一种方式 redis的订阅和发 ...
- Docker与虚拟机
Docker与虚拟机 简述 Docker 在容器的基础上,进行了进一步的封装,从文件系统.网络互联到进程隔离等等,极大的简化了容器的创建和维护.使得 Docker 技术比虚拟机技术更为轻便.快捷.下面 ...
- Jquery测试纠错笔记
一. 解析: 获取元素范围大小顺序依次为: $(#one).siblings("div")>$("#one~div")>$("#one + ...
- Gridview基础
gridview是封装好的,直接在设计界面使用,基本不需要写代码 1.绑定数据源 GridView最好与LinQDatasourse配合使用,相匹配绑定数据: 2.外观控制—— 点开有自动套用格式 布 ...