它就是要来了
noip数论一般会以三种形式呈现
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);
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #define ll long long 5 using namespace std; 6 ll n,k,x,a,b; 7 ll ksc(ll a,ll b,ll p){ll ans=0,base=a; 8 for(;b;b>>=1){if(b&1)ans+=base,ans%=p; 9 base*=2,base%p; 10 }return ans; 11 } 12 int main(){cin>>a>>b>>n; 13 cout<<ksc(a,b,n)<<endl; 14 }
#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=1,base=a; for(;x;x>>=1){if(x&1)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
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 #define ll long long 6 #define maxn 5000001 7 bool isprime[maxn];int n,m,sum=0,prime[maxn]; 8 void shai(){ 9 for(int i=2;i<maxn;i++){ 10 if(!isprime[i])prime[sum++]=i; 11 for(int j=0;j<sum&&i*prime[j]<maxn;j++){ 12 isprime[i*prime[j]]=1;if(i%prime[j]==0)break; 13 } 14 } 15 }int main(){ 16 cin>>n;shai();for(int i=0;i<=n;i++)cout<<prime[i]<<" "; 17 }
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 #define ll long long 6 #define maxn 5000001 7 bool isprime[maxn];int n,m,sum=0,prime[maxn],phi[maxn]; 8 void shai(){phi[1]=1,phi[2]=1; 9 for(int i=2;i<maxn;i++){ 10 if(!isprime[i])prime[sum++]=i,phi[i]=i-1; 11 for(int j=0;j<sum&&i*prime[j]<maxn;j++){ 12 isprime[i*prime[j]]=1;phi[i*prime[j]]=phi[i]*(prime[j]-1); 13 if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;} 14 } 15 } 16 }int main(){ 17 cin>>n;shai();for(int i=0;i<=n;i++)cout<<phi[i]<<" "; 18 }
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 #define ll long long 6 #define maxn 5000001 7 bool isprime[maxn];int n,m,sum=0,prime[maxn],phi[maxn],mu[maxn]; 8 void shai(){phi[1]=1,phi[2]=1;mu[1]=1; 9 for(int i=2;i<maxn;i++){ 10 if(!isprime[i])prime[sum++]=i,phi[i]=i-1,mu[i]=-1; 11 for(int j=0;j<sum&&i*prime[j]<maxn;j++){ 12 isprime[i*prime[j]]=1;phi[i*prime[j]]=phi[i]*(prime[j]-1);mu[i*prime[j]]=-mu[i]; 13 if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j],mu[i*prime[j]]=0;break;} 14 } 15 } 16 }int main(){ 17 cin>>n;shai();for(int i=0;i<=n;i++)cout<<mu[i]<<" "; 18 }
3.数论分块 这是个技巧……
4.矩阵快速幂