P1405题解

· · 题解

题目传送门

刚开始还想暴算,结果炸了……

upd 2024/2/27 修改代码可以通过 hack 数据。

前置知识

思路

给出欧拉定理的结论:

a^{\varphi(m)}\equiv 1 \pmod m ,\gcd(m,a)=1

其中 \varphi(m) 表示小于等于 m 的所有与 m 互质的个数。

给出费马小定理结论:

a^b \equiv a^{b \bmod (p-1)} \pmod p

再给出扩展欧拉定理的结论:

a^{b\bmod \varphi(m)}&,\mathrm{otherwise.} \end{cases}\pmod m

既然给出结论了,解题就很容易了,直接套用公式。(证明自己网上搜

这里给出如何得到 \varphi(m):

因为

\varphi(m)=m\prod^n_{i=1}(1-\frac{1}{p_i}) 则有以下代码: ```cpp inline ll Getphi(ll x){ ll res=x; for(ll i=2;i*i<=x;i++){ if(!(x%i)){ res/=i,res*=(i-1); while(!(x%i)) x/=i; } } if(x!=1) res/=x,res*=(x-1); return res; } ``` 因为模数固定,我们可以直接预算出需要用到的欧拉函数。 #### Code ```cpp #include <bits/stdc++.h> #define ll long long using namespace std; const ll Maxn=1234568; inline ll ksm(ll a,ll b,ll mod){ll z=1;while(b){if(b&1)z=z*a%mod;a=a*a%mod;b>>=1;}return z;} ll n,a[Maxn],phi[Maxn]; ll dfs(ll p,ll mod){ if(p==n+1||mod==1) return 1; ll t=dfs(p+1,phi[mod])+phi[mod]; return ksm(a[p],t,mod); } int main(){ scanf("%lld",&n); phi[10007]=10006;phi[10006]=5002;phi[5002]=2400;phi[2400]=640;phi[640]=256;phi[256]=128; phi[128]=64;phi[64]=32;phi[32]=16;phi[16]=8;phi[8]=4;phi[4]=2;phi[2]=1;phi[1]=1; for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); printf("%lld",dfs(1,10007)%10007); return 0; } ```