noip_最后一遍_1-数论部分

它就是要来了

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 }
View Code
#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;
}
View Code

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 }
View Code
 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 }
View Code
 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 }
View Code

3.数论分块 这是个技巧……

4.矩阵快速幂

猜你喜欢

转载自www.cnblogs.com/iboom/p/9905856.html