3)在求等比數列和取模的時候兩種方法:1. 用等比數列求和公式:S=a1*(q^n-1)/(q-1), 要用到(q-1)模9901的逆元,可以用歐拉定理或擴展歐幾裡得來求,但因為 mod 為素數,所以a的逆元為a^(mod-2)%mod,用快速冪來求。 2.遞歸形式的二分
對於逆元補充:費馬小定理(Fermat Theory)是數論中的一個重要定理,其內容為: 假如p是質數,且Gcd(a,p)=1,那麼 a(p-1) ≡1(mod p) 即:假如a是整數,p是質數,且a,p互質(即兩者只有一個公約數1),那麼a的(p-1)次方除以p的余數恆等於1。
//逆元法求解
#include#include #include #include #include #define maxn 10000 #define ll long long using namespace std; const ll MOD=9901; ll prime[maxn],num,flag[maxn+5]; ll pow_mod(ll a,ll b,ll p){ //快速冪 ll ret=1; while(b){ if(b&1) ret=(ret*a)%p; a=(a*a)%p; b>>=1; } return ret; } void get_prime(){ //篩素數 memset(flag,0,sizeof(flag)); num=0; for(ll i=2;i 1&&(n-1)%MOD==0) ans=ans*(pow_mod(n,m+1,MOD*(n-1))/(n-1))%MOD; //如果(n-1)%mod==0,不能求逆元了 else if(n>1) ans=ans*get_sum(n,m)%MOD; printf("%lld\n",ans); //剛開始沒加mod wa了好幾遍,因為這種方法ans可能為負 } return 0; }
//二分法求解
#include#include #include #include #include #define maxn 10000 #define ll long long using namespace std; const ll MOD=9901; ll prime[maxn],num,flag[maxn+5]; ll pow_mod(ll a,ll b,ll p){ //快速冪 ll ret=1; while(b){ if(b&1) ret=(ret*a)%p; a=(a*a)%p; b>>=1; } return ret; } void get_prime(){ //篩素數 memset(flag,0,sizeof(flag)); num=0; for(ll i=2;i 1) ans=ans*get_sum(n,m)%MOD; printf("%lld\n",ans); } return 0; }