Brute-force Algorithm

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2560    Accepted Submission(s): 657

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
 
Source
 
/**
题意:根据题意可以知道求 f(n) = f(n-1)*f(n-2)的值
f(1) = a
f(2) = b;
f(3) = a*b;
f(4) = a*b^2
f(5) = a^2*b^3
......
可以得知 a,b 的指数是斐波纳锲数列
做法:欧拉 + 矩阵 + 蒙哥马利幂模算法
      ps:没有搞清楚一点 在求矩阵的n-3次幂可以过 可是n-2次幂 不能过
**/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define SIZE 2
#define clr( a, b ) memset( a, b, sizeof(a) )
long long MOD;
struct Mat
{
long long mat[ SIZE ][ SIZE ];
int n;
Mat(int _n) {
n = _n;
clr(mat, );
}
void init() {
for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j) {
mat[i][j] = (i == j);
}
}
Mat operator * (const Mat& b) const {
Mat c(b.n);
for(int k = ; k < n; ++k)
for(int i = ; i < n; ++i) {
if(mat[i][k])
for(int j = ; j < n; ++j) {
c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j]) % MOD;
}
}
return c;
}
}; Mat fast_mod(Mat a, int b)
{
Mat res(a.n);
res.init();
while(b)
{
if(b & ) {
res = res * a;
}
a = a * a;
b >>= ;
}
return res;
} long long eular(long long n)
{
long long ans = n;
for(int i = ; i * i <= n; i++)
{
if(n % i == )
{
ans -= ans / i;
while(n % i == ) {
n /= i;
}
}
}
if(n > ) {
ans -= ans / n;
}
return ans;
}
long long modPow(long long s, long long index, long long mod)
{
long long ans = ;
s %= mod;
while(index >= )
{
if((index & ) == ) { //奇数
ans = (ans * s) % mod;
}
index >>= ;
s = s * s % mod;
}
return ans;
}
int main()
{
int T;
int Case = ;
scanf("%d", &T);
while(T--)
{
long long x, y, n, res, p;
cin >> x >> y >> p >> n;
printf("Case #%d: ", Case++);
if(p == || p == ) {
printf("0\n");
continue;
}
if(n == )
{
cout << x % p << endl;
continue;
}
else if(n == )
{
cout << y % p << endl;
continue;
}
MOD = eular(p);
Mat C();
C.mat[][] = ;
C.mat[][] = ;
C.mat[][] = ;
C.mat[][] = ;
C = fast_mod(C, n - );
long long aa = C.mat[][] + C.mat[][];
long long bb = C.mat[][] + C.mat[][];
res = ((modPow(x , aa, p) * modPow(y , bb, p)) % p + p) % p;
cout << res << endl;
}
return ;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define SIZE 2
#define clr( a, b ) memset( a, b, sizeof(a) )
long long MOD;
struct Mat
{
long long mat[ SIZE ][ SIZE ];
int n;
Mat(int _n) {
n = _n;
clr(mat, );
}
void init() {
for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j) {
mat[i][j] = (i == j);
}
}
Mat operator * (const Mat& b) const {
Mat c(b.n);
for(int k = ; k < n; ++k)
for(int i = ; i < n; ++i) {
if(mat[i][k])
for(int j = ; j < n; ++j) {
c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j]) % MOD;
}
}
return c;
}
}; Mat fast_mod(Mat a, int b)
{
Mat res(a.n);
res.init();
while(b)
{
if(b & ) {
res = res * a;
}
a = a * a;
b >>= ;
}
return res;
} long long eular(long long n)
{
long long ans = n;
for(int i = ; i * i <= n; i++)
{
if(n % i == )
{
ans -= ans / i;
while(n % i == ) {
n /= i;
}
}
}
if(n > ) {
ans -= ans / n;
}
return ans;
}
long long modPow(long long s, long long index, long long mod)
{
long long ans = ;
s %= mod;
while(index >= )
{
if((index & ) == ) { //奇数
ans = (ans * s) % mod;
}
index >>= ;
s = s * s % mod;
}
return ans;
}
int main()
{
int T;
int Case = ;
scanf("%d", &T);
while(T--)
{
long long x, y, n, res, p;
cin >> x >> y >> p >> n;
printf("Case #%d: ", Case++);
if(p == || p == ) {
printf("0\n");
continue;
}
if(n == )
{
cout << x % p << endl;
continue;
}
else if(n == )
{
cout << y % p << endl;
continue;
}
MOD = eular(p);
Mat C();
C.mat[][] = ;
C.mat[][] = ;
C.mat[][] = ;
C.mat[][] = ;
C = fast_mod(C, n - );
long long aa = C.mat[][] + C.mat[][];
long long bb = C.mat[][] + C.mat[][];
res = ((modPow(x , aa, p) * modPow(y , bb, p)) % p + p) % p;
cout << res << endl;
}
return ;
}

HDU-3221的更多相关文章

  1. hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)

    http://acm.hdu.edu.cn/showproblem.php?pid=3221 一晚上搞出来这么一道题..Mark. 给出这么一个程序.问funny函数调用了多少次. 我们定义数组为所求 ...

  2. HDU 3221 Brute-force Algorithm

              题意:问funny被调用了多少次,结果ModP,P不一定为质数.   首先很容易发现递推公式fn=fn-1*fn-2;写出前几项a,b,a*b,a*b^2,a^2*b^3,a^3* ...

  3. HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂

    装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1 ...

  4. SPOJ 5152 Brute-force Algorithm EXTREME && HDU 3221 Brute-force Algorithm 快速幂,快速求斐波那契数列,欧拉函数,同余 难度:1

    5152. Brute-force Algorithm EXTREME Problem code: BFALG Please click here to download a PDF version ...

  5. (记忆化搜索) FatMouse and Cheese(hdu 1078)

    题目大意:   给n*n地图,老鼠初始位置在(0,0),它每次行走要么横着走要么竖着走,每次最多可以走出k个单位长度,且落脚点的权值必须比上一个落脚点的权值大,求最终可以获得的最大权值   (题目很容 ...

  6. 转载:hdu 题目分类 (侵删)

    转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...

  7. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  9. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  10. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

随机推荐

  1. linux备忘录-程序管理与SELinux

    知识点 程序与程序(Process and Program) 通过执行一条指令或程序,则可以触发一个事件,并获得一个PID.当我们需要启动一个程序时,我们是启动一个二进制文件(binary file) ...

  2. centos7.4内核从3.10升级到4.14详细步骤

    由于我们的docker学习中的Overlay需要内核版本在3.12+,所以在安装完centos7.4之后要进行内核升级,下面是升级步骤:1.导入keyrpm --import https://www. ...

  3. AtomicIntegerFieldUpdater使用

    假设现在有这样的一个场景: 一百个线程同时对一个int对象进行修改,要求只能有一个线程可以修改. 看看下面程序是否正确: private static int a = 100; private sta ...

  4. lintcode-117-跳跃游戏 II

    117-跳跃游戏 II 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 样例 给出数组 ...

  5. 【SSH】——封装参数不确定的分页查询

    [前言] 在BS中,分页技术的应用相当频繁.说到分页,简单的分页就很好实现了,如果在分页的基础上再加上业务逻辑,这就使得分页的技术更加的灵活了. [简单分页] 我们先看一种简单的分页,为了做到复用,我 ...

  6. 玩adb和fastboot

    http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380143fd3d1027fa3c215cc790a1b18 ...

  7. JavaScript内置对象常用

    Math 提供了数学中常用的属性和方法,使用时直接用Math.属性/方法,而不需要new一个Math对象 Date 使用Date对象来对日期和时间进行操作.使用时,必须用new创建一个实例 windo ...

  8. EF to linq 左连接

    如果连接的数据不存在用 null 表示,则可以左连接查询,但是如果数据类型为 int 则会出错. var ng = (from g in _db.NET_NEWS_GROUP join z in _d ...

  9. win8.1 host被删,host无法修改,host无法复制进去解决方案

    1.C:\Windows\System32\drivers\etc\hosts  复制到桌面 2.删除C:\Windows\System32\drivers\etc\hosts 3.右键编辑文本--& ...

  10. [Leetcode] Add two numbers 两数之和

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...