您的位置:首页 > 其它

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

2017-08-01 20:57 253 查看
指数循环节:用于计算   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 <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const
4000
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<len;i++)
ans=ans*10+m[i]-'0';
}
else
{
for(int i=0;i<len;i++)
{
ans=ans*10+m[i]-'0';
ans%=tem;
}
ans+=tem;
}
ll sum=Pow(n,ans,c);
printf("%lld\n",sum);
}
int main()
{
ll n,c;
char m
;
Init();
while(scanf("%lld%s%lld",&n,m,&c)!=EOF)
{
solve(n,m,c);
}
return 0;
}

//3 2 4 20 10  1000


第二个题:Calculation
HDU - 2837 

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

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



没错就是这个式子。

求F(n);

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

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

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

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

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
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<<sum<<endl;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: