1. 程式人生 > >noip_最後一遍_1-數論部分

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.矩陣快速冪