歐拉降冪公式
bb%+
可以把大指數轉化成不超過的指數。
注意,這裏不要求a,p互質。
注意,這裏不要求a,p互質。
注意,這裏不要求a,p互質。(重要的事情說三遍!!!)
證明就不說啦,太菜了…
費馬小定理
首先p是一個質數,p。若gcd(a,p)=1時,p-1;若gcd(a,p)=p,p-1
可以看出費馬小定理是歐拉的特殊情況,即p是質數,
傳送門:Days passing
題意: 已知當前是周幾,求10000天后是周幾。
解析: 根據費馬小定理:7是質數,
如果N是7的倍數,%7=0,週數不變,
如果N不是7的倍數,%7=1,週數向前一天。
代碼:
#include<bits/stdc++.h>
using namespace std;
char N[10010];
string str;
int n=0,m;
int main(){
cin>>str;
scanf("%s",N+1);
scanf("%d",&m);
int len=strlen(N+1);
for(int i=1;i<=len;i++){
n=(n*10+N[i]-'0')%7;
}
if(n==0) cout<<str<<endl;
else {
if(str=="Mon") cout<<"Tue";
else if(str=="Tue") cout<<"Wed";
else if(str=="Wed") cout<<"Thu"<<endl;
else if(str=="Thu") cout<<"Fri"<<endl;
else if(str=="Fri") cout<<"Sat"<<endl;
else if(str=="Sat") cout<<"Sun"<<endl;
else if(str=="Sun") cout<<"Mon"<<endl;
}
return 0;
}
傳送門:sum
題意: 由1個數,2個數,3個數,…,n個數相加等於N(N爲大整數)的不同情況有多少種。
解析: 用擋板法,假設N=3,有:1 1 1,有兩個間隙。一個數時不需要加擋板爲C(2,0),兩個數時加一個擋板爲C(2,1),三個數時加兩個擋板爲C(2,2).那麼其實就是求:C(N-1,0)+C(N-1,1)+C(N-1,2)+…+C(N-1,N-1)=2N-1。
答案mod 1e9+7。那麼就對N進行大整數模擬取模1e9+6,最後再-1。再用快速冪即的答案。
代碼:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int mod=1e9+7;
char s[100010];
int N[100010];
int main(){
while(~scanf("%s",s+1)){
int len=strlen(s+1);
long long sum=0;
for(int i=1;i<=len;++i){
sum=(sum*10+s[i]-'0')%(mod-1);
}
sum--;
long long ans=1,tmp=2;
while(sum){
if(sum&1) ans=(ans*tmp)%mod;
tmp=(tmp*tmp)%mod;
sum/=2;
}
cout<<ans<<endl;
}
return 0;
}
傳送門:上帝與集合的正確用法
題意:
解析: 考慮歐拉降冪,f(p ) =22%oula(p )+p%p ,f(oula(p ))=22%oula(oula(p ) )+oula(p )%oula(p ),可以看出這是一個遞推式,如果直接遞推時間複雜度是否可行?
p到oula(p ) =p*(1-p/p1)…*(1-p/pn)。當p是偶數,一定有p1=2,會乘上1/2;當p是奇數,oula(p )一定是偶數,因爲它包含奇數質因子1-(1/奇數)會產生偶因子。
代碼:
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
int oula(int n){
int rea=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
rea=rea-rea/i;
do{
n/=i;
}while(n%i==0);
}
}
if(n>1) rea=rea-rea/n;
return rea;
}
int qp(int a,int b,int p){
int ans=1,tmp=a;
while(b){
if(b&1) ans=(1ll*ans*tmp)%p;
tmp=(1ll*tmp*tmp)%p;
b/=2;
}
return ans;
}
map<int,int> mmp;
int f(int p){
if(mmp[p]!=0) return mmp[p];
int ol=oula(p);
if(p==1||p==2){
return 0;
}
int t=qp(2,f(ol)+ol,p);
mmp[p]=t;
return t;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int p;
scanf("%d",&p);
printf("%d\n",f(p));
}
return 0;
}