【HDU3802】【降幂大法+矩阵加速+特征方程】Ipad,IPhone

Problem Description

In ACM_DIY, there is one master called “Lost”. As we know he is a “-2Dai”, which means he has a lot of money.
  
Well, Lost use Ipad and IPhone to reward the ones who solve the following problem.
  
In this problem, we define F( n ) as :
  
Then Lost denote a function G(a,b,n,p) as

Here a, b, n, p are all positive integer!
If you could tell Lost the value of G(a,b,n,p) , then you will get one Ipad and one IPhone!

Input

The first line is one integer T indicates the number of the test cases. (T <= 100)
Then for every case, only one line containing 4 positive integers a, b, n and p.
(1 ≤a, b, n, p≤2*109 , p is an odd prime number and a,b < p.)

Output

Output one line,the value of the G(a,b,n,p) .

Sample Input

4
2 3 1 10007
2 3 2 10007
2 3 3 10007
2 3 4 10007

Sample Output

40
392
3880
9941

Author

AekdyCoin

Source

ACM-DIY Group Contest 2011 Spring

Recommend

notonlysuccess   |   We have carefully selected several similar problems for you:  3805 3800 3801 3803 3804

【分析】

不知道怎么回事...跟网上的程序对拍了好像没错,怎么过不了...应该是有些比较坑的点....

不错的一道题目,前面的两项不说了,后面的那一项可以把二次方弄进去,然后变成一个用韦达定理做一个逆运算得到特征方程。

然后就有递推式了,然后就可以矩阵加速了。

然后因为幂实在是太大了,然后上降幂大法,然后没了。

其实还涉及到二次剩余的理论,如果前面没有那两个式子答案就错了....因为刚好是那两个式子,让不能用降幂大法的情况变成0...

  1 /*
  2 五代李煜
  3 《相见欢·林花谢了春红》
  4 林花谢了春红,太匆匆。无奈朝来寒雨晚来风。
  5 胭脂泪,相留醉,几时重。自是人生长恨水长东。
  6 */
  7 #include <iostream>
  8 #include <cstdio>
  9 #include <ctime>
 10 #include <cmath>
 11 #include <algorithm>
 12 #include <cstring>
 13 #include <string>
 14 #include <map>
 15 #include <set>
 16 #include <vector>
 17 #define LOCAL
 18 const int MAXN = 1000 + 10;
 19 const int INF = 0x7fffffff;
 20 using namespace std;
 21 typedef long long ll;
 22 ll mod;//代表取模的数字
 23 ll check, a, b, n, p;
 24 struct Matrix{
 25        ll num[5][5];
 26        //Matrix(){memset(num, 0, sizeof(num));}
 27 };
 28 //为了防止和第一种矩阵乘法搞混
 29 Matrix Mod(Matrix A, Matrix B, ll k){
 30      if (k == 0){//代表两种不同的乘法
 31         Matrix c;
 32         memset(c.num, 0, sizeof (c.num));
 33         for (ll i = 1; i <= 2; i++)
 34         for (ll j = 1; j <= 2; j++)
 35         for (ll k = 1; k <= 2; k++){
 36             ll tmp = (A.num[i][k] * B.num[k][j]);
 37             if (check) tmp %= (p - 1);
 38             c.num[i][j] += tmp;
 39             if (check) c.num[i][j] %= (p - 1);
 40         }
 41         //一旦大于了p-1代表当前出现的斐波那契数列会大于phi(p),可以使用降幂大法
 42         if ((c.num[1][1] + c.num[1][2]) > (p - 1)) check = 1;
 43         return c;
 44      }else if (k == 1){
 45            Matrix C;
 46            memset(C.num, 0, sizeof(C.num));
 47            for (ll i = 1; i <= 2; i++)
 48            for (ll j = 1; j <= 2; j++)
 49            for (ll k = 1; k <= 2; k++) {
 50                C.num[i][j] += (A.num[i][k] * B.num[k][j]) % p;
 51                C.num[i][j] = ((C.num[i][j] % p) + p) % p;
 52            }
 53            return C;
 54      }
 55 }
 56 //得到第x位的斐波那契数,也就是获得指数
 57 Matrix Matrix_pow(Matrix A, ll x, ll k){
 58        if (x == 1) return A;
 59        Matrix tmp = Matrix_pow(A, x / 2, k);
 60        if (x % 2 == 0) return Mod(tmp, tmp, k);
 61        else return Mod(Mod(tmp, tmp, k), A, k);
 62 }
 63 ll get(ll x){
 64      if (x == 0) return 1;
 65      else if (x == 1) return 1;
 66      Matrix A, B;
 67      A.num[1][1] = 1; A.num[1][2] = 1;
 68      A.num[2][1] = 1; A.num[2][2] = 0;
 69      x--;//为真实的需要乘的次数
 70      if (x == 0) return 1;
 71      B = Matrix_pow(A, x, 0);
 72      if (B.num[1][1] + B.num[1][2] > (p - 1)) check = 1;
 73      if (check == 0) return B.num[1][1] + B.num[1][2];
 74      else return (B.num[1][1] + B.num[1][2]) % (p - 1) + p - 1;
 75 }
 76 //有了a,b,pos就可进行矩阵加速了
 77 ll cal(ll a, ll b, ll pos){
 78     if (pos == 0) return 2 % p;
 79     else if (pos == 1) return  (2 * (a + b)) % p;
 80     Matrix A;
 81     A.num[1][1] = (2 * (a + b)) % p; A.num[1][2] = (((-(a - b) * (a - b)) % p) + p) % p;
 82     A.num[2][1] = 1; A.num[2][2] = 0;
 83     pos--;
 84     Matrix B;
 85     B = Matrix_pow(A, pos, 1);
 86     return (B.num[1][1] * A.num[1][1]) % p + (B.num[1][2] * 2) % p;
 87 }
 88 ll pow(ll a, ll b){
 89     if (b == 0) return 1 % p;
 90     if (b == 1) return a % p;
 91     ll tmp = pow(a, b / 2);
 92     if (b % 2 == 0) return (tmp * tmp) % p;
 93     else return (((tmp * tmp) % p) * a) % p;
 94 }
 95
 96 int main(){
 97     int T;
 98     scanf("%d", &T);
 99     while (T--){
100           //for (int i = 1; i ,=)
101           scanf("%lld%lld%lld%lld", &a, &b, &n, &p);
102           check = 0;//判断f(n)是否大于p
103           ll pos = get(n);
104           ll Ans = cal(a, b, pos);
105           ll f1, f2;
106           f1 = (pow(a, (p - 1) / 2) + 1) % p;
107           f2 = (pow(b, (p - 1) / 2) + 1) % p;
108           Ans = (((f1 * f2) % p) * Ans) % p;
109           printf("%lld\n", Ans);
110     }
111     //p = 0x7fffffff;
112     //printf("%lld", get(5));
113     //for (int i = 0; i <= 10; i++) printf("%lld\n", get(i));
114     return 0;
115 }

时间: 2024-11-10 16:42:05

【HDU3802】【降幂大法+矩阵加速+特征方程】Ipad,IPhone的相关文章

矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

【矩阵加速】 矩阵 快速幂

矩阵的快速幂是用来高效地计算矩阵的高次方的.将朴素的o(n)的时间复杂度,降到log(n). 这里先对原理(主要运用了矩阵乘法的结合律)做下简单形象的介绍: 一般一个矩阵的n次方,我们会通过连乘n-1次来得到它的n次幂. 但做下简单的改进就能减少连乘的次数,方法如下: 把n个矩阵进行两两分组,比如:A*A*A*A*A*A => (A*A)*(A*A)*(A*A) 这样变的好处是,你只需要计算一次A*A,然后将结果(A*A)连乘自己两次就能得到A^6,即(A*A)^3=A^6.算一下发现这次一共乘

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

HDU 5564 Clarke and digits 状压dp+矩阵加速

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5564 题意: 求长度在[L,R]范围,并且能整除7的整数的总数. 题解: 考虑最原始的想法: dp[i][j][k]表示长度为i,并且对7取模得到j的以k结尾的数. 则有状态转移方程dp[i+1][(h*10)+l)%7][k]+=dp[i][h][k'](k+k'!=K). 但是i范围是1~10^9,需要矩阵加速. 这里对dp[i][j][k]的[j][k]两个状态进行压缩,得到转移矩阵mat[

斐波那契数列F(n)【n超大时的(矩阵加速运算) 模板】

hihocoder #1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示

iPad iPhone iPod touch

Price Display Chip iSight Camera FaceTime Camera RAM JD Price iPad Air 3588 2048X1536 A7 5MP 1.2MP 1024 3388 iPad R 2888 2048X1536 A6X 5MP 1.2MP 1024 2888 iPad mini R 2888 2048X1536 A7 5MP 1.2MP 1024 2758 iPad mini 2098 1024X768 A5 5MP 1.2MP 512 1998

【BZOJ3884】【降幂大法】上帝与集合的正确用法

Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“元”构成的集合.容易发现,一共有两种不同的“α”. 第三天, 上帝又创造了一个新的元素,称作“β”.“β”被定义为“α”构成的集合.容易发现,一共有四种不同的“β”. 第四天, 上帝创造了新的元素“γ”,“γ”被定义为“β”的集合.显然,一共会有16种不同的“γ”. 如果按照这样下去,上帝创造的第四种元

P1939 【模板】矩阵加速(数列)

链接:P1939 [模板]矩阵加速(数列) 题目描述 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值. 输入输出格式 输入格式: 第一行一个整数T,表示询问个数. 以下T行,每行一个正整数n. 输出格式: 每行输出一个非负整数表示答案. 输入输出样例 输入样例#1: 3 6 8 10 输出样例#1: 4 9 19 说明 对于30%的数据 n<=100: 对于60%的数据 n<=2*10^7

解决Xcode在ipad/iphone 9.2 系统真机测试时出现could not find developer disk image问题

解决Xcode在ipad/iphone 9.2 系统真机测试时出现could not find developer disk image问题 方法1:拷贝这个文件(http://download.csdn.net/detail/cvbtvbwu/9340467)到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport,然后重新启动xcode(完全退出)就可以了. 方法2:更新Xcod