Brute-force Algorithm_矩阵快速幂&&欧拉公式*****

Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it.
Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.
For each test cases, there are four integers a, b, P and n in a single line.
You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.
3 4 10 3
4 5 13 5
3 2 19 100
Case #2: 11
Case #3: 12
【参考】http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html
【题意、思路】f[n]=f[n-1]*f[n-2];
f的前面几项可以罗列出来:
a^1*b^0,a^0*b^1,a^1*b^1,a^1*b^2,a^2*b^3....
可以发现a的指数和b的指数均类似于斐波那契数列。
用矩阵的快速幂可以很快的求出第n项a和b的指数分别是多少。
但是这个指数会非常大,存不下来,需要对一个数去模。
这里需要用到一个公式:
A^B%C=A^( B%Phi[C] + Phi[C] )%C (B>=Phi[C])
Phi[C]表示不大于C的数中与C互质的数的个数,可以用欧拉函数来求:
找到C的所有素因子。
Phi[C]=C*(1-1/q1)*(1-1/q2)*(1-1/q3)*....*(1-1-qk);
q1,q2,q3...qk表示C的素因子。
到这里基本上就能解决了。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=;
long long int a,b,p,n;
int vis[N],prime[N],K;
long long int phi;
struct mat
{
long long int a[][];
};
void init()
{
memset(vis,,sizeof(vis));
for(int i=;i<=;i++)
{
if(vis[i]==)
{
for(int j=i+i;j<=;j+=i)
{
vis[j]=;
}
}
}
K=;
for(int j=;j<=;j++)
if(vis[j]==) prime[++K]=j;
}
mat power(mat a1,mat b1)//矩阵乘法
{
mat c;
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
c.a[i][j]=;
for(int k=;k<=;k++)
{
c.a[i][j]+=a1.a[i][k]*b1.a[k][j];
if(c.a[i][j]>phi)
c.a[i][j]=c.a[i][j]%phi+phi;
}
}
}
return c;
}
mat mod(mat x,long long int k)
{
mat ans;
ans.a[][]=;
ans.a[][]=;
ans.a[][]=;
ans.a[][]=;
while(k)
{
if(k%) ans=power(ans,x);
x=power(x,x);
k/=;
}
return ans;
}
long long int mod1(long long int a,long long int k)
{
long long int ans;
ans=;
while(k)
{
if(k%)
{
ans=ans*a;
ans%=p;
}
a=a*a;
a%=p;
k/=;
}
return ans%p;
}
int main()
{
int t,cas=;
long long int aa,bb,num,num2,num1;
mat now,ans;
init();
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld%lld",&a,&b,&p,&n);
printf("Case #%d: ",cas++); if(n==) {printf("%lld\n",a%p);continue;}
else if(n==) {printf("%lld\n",b%p);continue;}
else if(n==) {printf("%lld\n",a*b%p);continue;}
if(p==) {printf("0\n");continue;}
else
{
now.a[][]=;
now.a[][]=;
now.a[][]=;
now.a[][]=;
// A^B % C = A ^ ( B % phi[C] + phi[C] ) %C ( B >= phi[C] ) ,phi[C]表示与C互质的数的个数
phi=;
num=p;
for(int i=; i<=K; i++)
{
if(prime[i]>p) break;
if(p%prime[i]==)
{
phi*=(prime[i]-);
num/=prime[i];
} }
//phi[C]=C*(1-1/p1)*(1-1/p2)*...*(1-1/pt);p1,p2,...pt表示C的素因子
phi*=num;//phi表示phi[c]
ans=mod(now,n-);//求指数 num1=ans.a[][];//a的指数
num2=ans.a[][]+ans.a[][];//b的指数
if(num2>phi) num2=num2%phi+phi; aa=mod1(a,num1);//a^num1%p
bb=mod1(b,num2);//b^num2%p
printf("%lld\n",aa*bb%p);
} }
return ;
}
Brute-force Algorithm_矩阵快速幂&&欧拉公式*****的更多相关文章
- BNU29139——PvZ once again——————【矩阵快速幂】
PvZ once again Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java cla ...
- 矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)
题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Go ...
- 51nod 算法马拉松18 B 非010串 矩阵快速幂
非010串 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个01字符串满足不存在010这样的子串,那么称它为非010串. 求长度为n的非010串的个数.(对1e9+7取模) ...
- 51nod 1113 矩阵快速幂
题目链接:51nod 1113 矩阵快速幂 模板题,学习下. #include<cstdio> #include<cmath> #include<cstring> ...
- 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】
还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...
- HDU5950(矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:f(n) = f(n-1) + 2*f(n-2) + n^4,f(1) = a , f(2 ...
- 51nod 1126 矩阵快速幂 水
有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给出A,B和N,求f(n)的值. Input 输 ...
- hdu2604(递推,矩阵快速幂)
题目链接:hdu2604 这题重要的递推公式,找到公式就很easy了(这道题和hdu1757(题解)类似,只是这道题需要自己推公式) 可以直接找规律,推出递推公式,也有另一种找递推公式的方法:(PS: ...
- 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式
矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b * A B = a*A+b*C a*c+b*D c d ...
随机推荐
- iisreset和w3wp的关系
iisreset是iis自带一个命令行工具.用法: iisreset [computername] /RESTART 停止然后重新启动所有 Internet 服务. /START ...
- JDE隐藏Constant等(Hide Object)
Grid中隐藏列,列值可以使用属性配置,但是列表头Constant需要用函数修改,如下所示:
- BZOJ1590 [Usaco2008 Dec]Secret Message 秘密信息
建立一颗trie树,记录下来每个点以它为结尾的字符串的个数cnt,和它的子树内有多少字符串size 于是查询的时候就只需要把沿途的cnt加起来,再加上最后的size就好了 /************* ...
- netbios wins dns LLMNR
NetBIOS名称 Network Basic Input/Output System (RFC-1001,1002)网络基本输入/输出系统协议 NetBIOS是一种高级网络接口,最初是在硬件中实 ...
- 设置ASP.NET MVC站点默认页为html页
问题由来 部署了一个Asp.Net MVC的站点,其功能只是作为移动端的服务器,服务器空间里面除了CMS以外就没有其他的页面了.这对于我们来说确实是有点浪费了. 可以放点静态的啥小东西放在上面玩一玩. ...
- c实现的iOS http下载类。支持自己设定http 头(比如cookie等)
也许有人要问为什么要自己用c写? 原因是: 1 我是菜鸟 2 我最最初选择了AsyncSocket,弄了很久,基本上稳定了,但有时候出现了数据不完整,但我又没办法在这个时候识别到并重试:所以不完美,最 ...
- NSString length的坑。
说坑,可能过头了,是我理所当然的把OC看作C了, char* cstr = "zh中文12"; NSString* s = [NSString stringWithUTF8Stri ...
- 7 libjpeg使用
一.交叉编译libjepg编译 tar xzf libjpeg-turbo-1.2.1.tar.gz ./configure –help ./configure --prefix=/work/proj ...
- POJ 3207 2-sat
题目大意: 在圆上顺时针n个点,给定m个连接,可以通过圆内或者圆外相交,问能不能找到一种方式,使这些连接的边都不相交 这里很容易看出的是,这些边只有在圆外或者圆内两种连接方式,而且必须选择其中一种 所 ...
- CSU 1111 D(Contest #3)
有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园.A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕.C 太太因为正身怀六甲无法加入她们的行列,便出了90元.请 ...