高次幂取模

公式:A^x%C=A^(x%phi(C)+phi(C))%C,具体证明见ACblog

FZU1759   HDU2837  HDU3609 HDU3221


ACcode:


/**
hdu3609
*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int MOD=1e8;

LL a;
int k;
int p[220]={100000000};

int quick_pow(LL x,int y,int mod)
{
    x%=mod;
    int ans=1;
    for (;y;y>>=1)
    {
        if (y&1) ans=((LL)ans*x)%mod;
        x=(x*x)%mod;
    }
    return ans;
}

LL judge(LL x,LL y)
{
    LL ans=1;
    for (int i=1;i<=y;i++)
    {
        ans*=x;
        if (ans>=MOD) return MOD;
    }
    return ans;
}

int eular(int n)
{
    int ans=1;
    int y=(int)sqrt(double(n));
    for (int i=2;i<=y;i++)
    {
        if (n%i==0)
        {
            ans*=i-1,n/=i;
            for (;n%i==0;ans*=i,n/=i);
        }
    }
    if (n>1) ans*=n-1;
    return ans;
}

int main()
{
    for (int i=1;i<200;i++) p[i]=eular(p[i-1]);
    while (~scanf("%I64d",&a))
    {
        scanf("%d",&k);
        if(a == 0 && k % 2 == 0) {puts("1"); continue;}
        int ans=a%p[k-1];
        LL s=a;
        for (int i=2,j=k-2;i<=k;j--,i++)
        {
            ans=quick_pow(a,ans,p[j]);
            ans+= s>=p[j]? p[j]:0;
            if (s<MOD) s=judge(a,s);
        }
        printf("%d\n",ans%MOD);
    }
    return 0;
}

/**
FZU1759
*/
#include<cstdio>
#include<cstring>

typedef long long LL;

char b[1000010];

LL eular(LL k)
{
    LL s=1;
    for (LL i=2;i*i<=k;i++)
    {
        if (k%i==0)
        {
            k=k/i,s*=(i-1);
            while (k%i==0)
            k=k/i,s*=i;
        }
    }
    if (k>1) s*=k-1;
    return s;
}

LL quick_pow(LL x,LL y,LL p)
{
    LL ans=1;
    for (;y;y>>=1)
    {
        if (y&1) ans=(LL)ans*x%p;
        x=(LL)x*x%p;
    }
    return ans;
}

int main()
{
    LL a,c,x,y;
    while (~scanf("%I64d",&a))
    {
        scanf("%s",b);
        scanf("%I64d",&c);
        LL phi=eular(c);
        x=y=0;
        LL len=strlen(b);
        for (LL i=0;i<len;i++)
        {
            x=x*10+b[i]-'0';
            if (y==0&&x>=phi) y=phi;
            x%=phi;
        }
        printf("%I64d\n",quick_pow(a,x+y,c));
    }
    return 0;
}

/**
hdu2837
*/
#include<cstdio>
#include<cstring>
typedef long long LL;

LL s,n,m;

LL eular(LL k)
{
    LL s=1;
    for (LL i=2;i*i<=k;i++)
    {
        if (k%i==0)
        {
            k=k/i,s*=(i-1);
            while (k%i==0)
            k=k/i,s*=i;
        }
    }
    if (k>1) s*=k-1;
    return s;
}

LL quick_pow(LL x,LL y,LL p)
{
    LL ans=1;
    for (;y;y>>=1)
    {
        if (y&1) ans=(LL)ans*x%p;
        x=(LL)x*x%p;
    }
    return ans;
}

LL judge(LL x,LL y)
{
    LL ans=1;
    for (int i=1;i<=y;i++)
    {
        ans*=x;
        if (ans>=m) break;
    }
    return ans;
}

LL Max(LL a1,LL a2)
{
    return a1>a2?a1:a2;
}

LL dfs(LL n,LL mod)
{
    LL phi=eular(mod);
    if (n==0)
    {
        s=1;
        return 1;
    }
    else
    {
        LL x,y,ans;
        x=n%10,y=n/10;
        y=dfs(y,phi);
        ans=quick_pow(x,y,mod);
        if (x==0&&y==0) ans=1;
        s=Max(ans,judge(x,s));
        if (s>=mod) ans+=mod;
        return ans;
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%I64d %I64d",&n,&m);
        printf("%I64d\n",dfs(n,m)%m);
    }
    return 0;
}

/**
hdu3221
*/
#include<cstdio>
#include<cstring>
typedef long long LL;

struct matrix
{
    LL r[2][2];
};

LL a,b,p,n,phi,f;

LL eular(LL k)
{
    LL s=1;
    for (LL i=2;i*i<=k;i++)
    {
        if (k%i==0)
        {
            k=k/i,s*=(i-1);
            while (k%i==0)
            k=k/i,s*=i;
        }
    }
    if (k>1) s*=k-1;
    return s;
}

LL quick_pow(LL x,LL y,LL p)
{
    LL ans=1;
    for (;y;y>>=1)
    {
        if (y&1) ans=ans*x%p;
        x=x*x%p;
    }
    return ans;
}

matrix multi(matrix x,matrix y)
{
    matrix t;
    for (int i=0;i<2;i++)
    {
        for (int j=0;j<2;j++)
        {
            t.r[i][j]=x.r[i][0]*y.r[0][j];
            t.r[i][j]+=x.r[i][1]*y.r[1][j];
        }
    }
    return t;
}

matrix judge(matrix t)
{
    for (int i=0;i<2;i++)
    for (int j=0;j<2;j++)
    {
        if (t.r[i][j]<0)
        {
            printf("-1\n");
            return t;
        }
        if (t.r[i][j]>=phi)
        f=1,t.r[i][j]%=phi;
    }
    return t;
}

matrix facbo(LL k,matrix c)
{
    matrix  t={1,0,0,1};
    while (k)
    {
        if (k&1)
        {
            t=multi(t,c);
            t=judge(t);
        }
        c=multi(c,c),k>>=1;
        if (k) c=judge(c);
    }
    return t;
}

matrix init(matrix t)
{
    t.r[1][1]=0;
    t.r[0][0]=t.r[1][0]=t.r[0][1]=1;
    return t;
}

int main()
{
    int T,cas=0;
    LL ans,pa,pb;
    matrix e;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%I64d%I64d%I64d%I64d",&a,&b,&p,&n);
        if (n==1) ans=a;
        else if (n==2) ans=b;
        else
        {
            f=0;
            phi=eular(p);
            e=facbo(n-3,init(e));
            pa=e.r[0][0]+f*phi;
            pb=e.r[0][0]+e.r[0][1];
            if (pb>=phi) f=1;
            pb=pb%phi+f*phi;
            ans=quick_pow(b,pb,p)*quick_pow(a,pa,p);
        }
        printf("Case #%d: %I64d\n",++cas,ans%p);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值