UPC:2219 A^X mod P(预处理空间换时间)

题意:按公式求f[x],再按公式求结果。

思路:直接搞的话f[i]可能高达10^9,n10^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)^aA^b的幂并存入数组(0<=a<=10^4,0<=b<=10^5)。这样求A^f[n]就是O1),求最后结果的过程可以在On)内完成。

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值