noip_最後一遍_1-數論部分
阿新 • • 發佈:2018-11-04
它就是要來了
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> 2View Code#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; }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.矩陣快速冪