UPC:2219 A^X mod P(預處理空間換時間)
阿新 • • 發佈:2019-02-13
題意:按公式求f[x],再按公式求結果。
思路:直接搞的話f[i]可能高達10^9,n為10^6,即使用快速冪也會超時。用空間換時間是一種常見的降低複雜度的辦法。對於任意一個數字X,它可以變成X=a*N+b(N為常數)。基於這個思路可以把f[n]=a*N+b,如果取N=10^5,那麼可以保證a最大為10^4,b最大為10^5。這樣A^f[n]=A^(a*N+b)=A^(a*N)*A^b=(A^N)^a*A^b。其中A^N為常數,可以線性時間求得。這樣可以線上性時間內求得(A^N)^a和A^b的冪並存入陣列(0<=a<=10^4,0<=b<=10^5)。這樣求A^f[n]就是O(1),求最後結果的過程可以在O
#include <iostream> #include <vector> #include <cstring> #include <cstdio> using namespace std; typedef long long LL; const int maxn=1000005; const int N=100000; LL f[maxn]; LL bx[N+10]; LL ax[N+10]; int main() { int T,kase=0; cin>>T; while(T--) { LL n,A,K,a,b,m,P; cin>>n>>A>>K>>a>>b>>m>>P; A%=P; f[1]=K; for(int i=2;i<=n;++i) f[i]=(a*f[i-1]+b)%m; bx[0]=1%P; for(int i=1;i<=N;++i) bx[i]=bx[i-1]*A%P; LL Ax=1%P; for(int i=1;i<=N;++i) Ax=(Ax*A)%P; ax[0]=1%P; for(int i=1;i<=N;++i) ax[i]=ax[i-1]*Ax%P; LL ans=0; for(int i=1;i<=n;++i) { int x=f[i]/N; int y=f[i]%N; LL t=ax[x]*bx[y]%P; ans=(ans+t)%P; } cout<<"Case #"<<++kase<<": "<<ans<<endl; } return 0; }