指数循环节 处理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大的时候需要先模再算。
而且进行快速幂的时候需要处理一下。好像叫个啥快速乘,其实就是快速幂 的另一种版本。
代码:
第二个题: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;
}
例子: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;
}
相关文章推荐
- 指数循环节问题
- FZU oj 1759 Super A^B mod C (快速幂+指数循环节+欧拉函数)
- FZU 1759 Super A^B mod C 指数循环节
- FZU 1759 Super A^B mod C (快速幂+指数循环节)
- fzu 1759Super A^B mod C 指数循环节
- FZU 1759-Super A^B mod C(指数循环节)
- Super A^B mod C(指数循环节+欧拉函数)
- 指数循环节问题
- 正确处理ipv6和内购(IAP)及掉单问题
- tomcat程序部署到weblogic遇到的问题:对于字符串空的处理不一样
- 国庆期间拿福能CN官网问题竟无人处理?
- 关于EXP-00106: 数据库链接口令无效 问题处理
- 用数组处理求Fibonacci数列问题
- mysql重新安装报错问题及乱码处理
- ajax jsonp跨域处理问题
- python中处理中文编码问题
- PHP文件上传问题汇总(文件大小检测、大文件上传处理)
- IIS处理并发请求时出现的问题及解决
- shell中对单引号的处理问题
- oracle drop用户cascade 无法顺利删除问题处理-ORA-00604和ORA-00942错误