指数循环节 处理A^B 问题 Super A^B mod C + Calculation


指数循环节:用于计算   A^B    ;

例子:http://acm.fzu.edu.cn/problem.php?pid=1759

Given A,B,C, You should quickly calculate the result of A^B mod C.             (1<=A,C<=1000000000,1<=B<=10^1000000).

A和B都贼大,所以就需要用一个公式来减少计算;



需要注意的是这个公式有个条件。

但是上面这个题好像用不上。

说一下思路吧:当B比较小的时候就直接计算,当B大的时候需要先模再算。

而且进行快速幂的时候需要处理一下。好像叫个啥快速乘,其实就是快速幂 的另一种版本。

代码:


#include 
#include 
#include 
using namespace std;
const int N=1000005;
typedef long long ll;


int phi(int n)
{
    int rea = n;
    for(int i=2; i*i<=n; i++)
    {
        if(n % i == 0)
        {
            rea = rea - rea / i;
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1)
        rea = rea - rea / n;
    return rea;
}
ll mul(ll a,ll b,ll c)
{
    ll ans=0;
    a%=c;
    while(b)
    {
        if(b&1)
        {
            ans=(ans+a)%c ;
            //b--;
        }
        b>>=1;
        a=(a+a)%c;
    }
    return ans;
}
ll Pow(ll a,ll b,ll c)
{
    ll ans=1;
    a%=c;
    while(b)
    {
        if(b&1)
        {
            ans=mul(ans,a,c);
            //b--;
        }
        b>>=1;
        a=mul(a,a,c);
    }
    return ans;
}
void solve(int n,char m[],int c)
{
    ll tem=euler(c);
    ll ans=0;
    ll len=strlen(m);
    if(len<=15)
    {
        for(int i=0;i


第二个题:Calculation HDU - 2837 

这个题就没有那么水了,反正我WA了好多发(可能是我太水)

这个题就是求一个递推式。


没错就是这个式子。

求F(n);

具体做法就是先一直递推上去,然后再用公式了。

注意公式所给的条件,必须满足B>phi( C),不然会WA。

快速幂取模的时候要注意区分 B是否较大。

每一层都要判断b是否大于等于它外面一层的模

代码:


#include
#include
#include
#include
using namespace std;

typedef long long ll;

ll euler(ll n)
{
    ll res=n,i;
    for(ll i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        res=res/n*(n-1);
    return res;
}
ll Pow(ll a,ll b,ll m)
{
    ll ans=1;
    a%=m;
    while(b)
    {
        if(b&1)
        {
            ans=ans*a%m;
            b--;
        }
        a=a*a%m;
        b>>=1;
    }
    return ans%m;
}
ll Fuck(ll a,ll b,ll mod)
{
    ll res=1;
    for(ll i=1;i<=b;i++)
    {
        res*=a;
        if(res>=mod)
            return res;
    }
    return res;
}
ll D(ll n,ll m)
{
    ll p=euler(m);
    if(n<10)
        return n;
    ll x=D(n/10,p);
    ll ans=Fuck(n%10,x,m);
    if(ans>=m)
    {
        ll res=Pow(n%10,x+p,m);   //
        if(res==0)
            res+=m;
        return res;
    }
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    ll n,m;
    while(T--)
    {
        scanf("%lld%lld",&n,&m);
            ll sum=D(n,m)%m;
            cout<



 



你可能感兴趣的:(模板,欧拉函数)