Problem Description
Professor Brute is not good at algorithm design. Once he was asked to solve a path finding problem. He worked on it for several days and finally came up with the following 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.

 
Input
There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases.

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.

 
Output
For each test case, output the answer with case number in a single line.
 
Sample Input
3
3 4 10 3
4 5 13 5
3 2 19 100
 
Sample Output
Case #1: 2
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_矩阵快速幂&&欧拉公式*****的更多相关文章

  1. BNU29139——PvZ once again——————【矩阵快速幂】

    PvZ once again Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java cla ...

  2. 矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

    题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Go ...

  3. 51nod 算法马拉松18 B 非010串 矩阵快速幂

    非010串 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个01字符串满足不存在010这样的子串,那么称它为非010串. 求长度为n的非010串的个数.(对1e9+7取模) ...

  4. 51nod 1113 矩阵快速幂

    题目链接:51nod 1113 矩阵快速幂 模板题,学习下. #include<cstdio> #include<cmath> #include<cstring> ...

  5. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  6. 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 ...

  7. 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 输 ...

  8. hdu2604(递推,矩阵快速幂)

    题目链接:hdu2604 这题重要的递推公式,找到公式就很easy了(这道题和hdu1757(题解)类似,只是这道题需要自己推公式) 可以直接找规律,推出递推公式,也有另一种找递推公式的方法:(PS: ...

  9. 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式

    矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b     *     A B   =   a*A+b*C  a*c+b*D c d     ...

随机推荐

  1. Github注册流程和使用体验

    大家好,我叫施蓓蓓,学号1413042063,在网络工程143班,我的兴趣爱好有很多,特别是在专业方面,比如软件工程.操作系统.网络通信技术.计算机组成原理等,我对游戏十分感兴趣,以后就业会朝这方面发 ...

  2. 转载:Javascript作用域原理

    首先看一个例子: var name = 'laruence'; function echo() { alert(name); var name = 'eve'; alert(name); alert( ...

  3. AES加密 16进制与二进制转换

    import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax ...

  4. 随机分类器的ROC和Precision-recall曲线

    随机分类器,也就是对于一个分类问题,随机猜测答案.理论上,随机分类器的性能是所有分类器的下界.对随机分类器的理解,可以帮助更好的理解分类器的性能指标.随机分类器的性能也可以作为评价分类器的一个基础.所 ...

  5. ruby开源项目之Octopress:像黑客一样写博客(zhuan)

    ruby开源项目之Octopress:像黑客一样写博客 百度权重查询 词库网 网站监控 服务器监控 SEO监控 Swift编程语言教程 今年一直推荐的一种写作方式.markdown语法快速成文,git ...

  6. bzoj 2440: [中山市选2011]完全平方数

    #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #defin ...

  7. 河流 tyvj1506

    题目大意: 给出一棵n个节点的有根树,一开始 树根 是一个控制点,现在要增加m个控制点,使得总费用最少. 给出每个节点的父节点以及到父节点的距离,还有这个节点的权值, 一个节点的费用 即它的权值 乘以 ...

  8. 常州培训 day3 解题报告

    第一题: 给出数轴正半轴上N个点的坐标和其权值,给出初始体力值M,人一开始在位置0,体力值会随着走过路程的增加而增加,走多少个单位的路消耗多少体力值.到每个点可以打掉,消耗的体力值就是其权值.求 最多 ...

  9. sql面向过程用法

    sql可以看成是面向过程的编程语言.该语言中,有string.date.table这样的类型等等 一.操作表 sql相当于一个函数,输入是两个或多个表(A, B, ...) 求集合: 并集 union ...

  10. Android 动画特效

    一.渐变动画 AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f); // fromAlpha , toAlpha aa.setDuration(200 ...