HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识
求$G(a,b,n,p) = (a^{\frac {p-1}{2}}+1)(b^{\frac{p-1}{2}}+1)[(\sqrt{a} + \sqrt{b})^{2F_n} + (\sqrt{a} - \sqrt{b})^{2F_n}] (mod p)$
左边可以看出是欧拉判定准则,那么只有当a,b其中一个满足是模p下的非二次剩余时G()为0。
右边的式子可以先把平方放进去,发现这个已经是通项公式了,那么$a+b+\sqrt{ab}$和$a+b-\sqrt{ab}$就是它的特征根了,反代回二阶特征方程,得到递推式的两个系数$2(a+b)$,$-(a-b)^2$,然后可以使用矩阵快速幂了,注意其项数是$F(n)$,指数循环节,欧拉降幂,其矩阵快速幂的过程中模p-1就行了。
/** @Date : 2017-10-11 22:30:33
* @FileName: HDU 3802 斐波那契特征方程解递推式 矩阵快速幂.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; LL mod; LL fpow(LL a, LL n)
{
LL res = 1LL;
while(n)
{
if(n & 1LL) res = (res * a % mod + mod) % mod;
a = (a * a % mod + mod) % mod;
n >>= 1LL;
}
return res;
} struct matrix
{
LL mat[2][2];
matrix(){MMF(mat);}
void id(){
mat[0][0] = mat[1][1] = 1LL;
}
matrix operator *(const matrix &b){
matrix c;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++)
{
c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j] % mod) % mod;
}
return c;
}
matrix operator ^(LL n){
matrix res;
matrix a = *this;
res.id();
while(n)
{
if(n & 1LL)
res = res * a;
a = a * a;
n >>= 1LL;
}
return res;
}
}; LL fib(LL n)
{
mod--;
matrix T;
T.mat[0][0] = 1LL, T.mat[0][1] = 1LL;
T.mat[1][0] = 1LL, T.mat[1][1] = 0LL;
matrix tmp = (T^(n-1));
LL ans = ((tmp.mat[0][0] + tmp.mat[1][0])%mod + mod) % mod;
mod++;
return ans;
} LL fun(LL a, LL b, LL n)
{
LL ans = (fpow(a, (mod - 1)>>1) + 1LL) * (fpow(b, (mod-1)>>1) + 1LL) % mod;//注意这里也要取模...
if(ans == 0)
return 0;
if(n < 2)
return (a + b) * 2LL % mod * ans % mod;
LL e = fib(n);
//cout << e << endl;
if(e == 0)
e = mod - 1;
matrix A;
A.mat[0][0] = (a + b) * 2LL % mod, A.mat[0][1] = 1LL;
A.mat[1][0] = (b - a) * (a - b) % mod, A.mat[1][1] = 0LL;
A = A^(e - 1);
ans = (ans * ((a + b) * 2LL % mod * A.mat[0][0] + A.mat[1][0] * 2LL % mod) % mod) % mod;
while(ans < 0)
ans += mod;
return ans;
}
int main()
{
int T;
cin >> T;
while(T--)
{
LL a, b, n;
scanf("%lld%lld%lld%lld", &a, &b, &n, &mod);
LL ans = fun(a, b, n);
printf("%lld\n", ans);
}
return 0;
}
HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识的更多相关文章
- 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式
矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b * A B = a*A+b*C a*c+b*D c d ...
- HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )
题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但 ...
- 矩阵快速幂(queue递推)
http://acm.hdu.edu.cn/showproblem.php?pid=2604 Queuing Time Limit: 10000/5000 MS (Java/Others) Me ...
- Google Code Jam 2008 Round 1A C Numbers(矩阵快速幂+化简方程,好题)
Problem C. Numbers This contest is open for practice. You can try every problem as many times as you ...
- HDU 1757 矩阵快速幂加速递推
题意: 已知: 当x<10时:f(x)=x 否则:f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + --+ a9 * f(x-10); 求:f(x ...
- HDU 2855 (矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2855 题目大意:求$S(n)=\sum_{k=0}^{n}C_{n}^{k}Fibonacci(k)$ ...
- HDU 4471 矩阵快速幂 Homework
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4471 解题思路,矩阵快速幂····特殊点特殊处理····· 令h为计算某个数最多须知前h个数,于是写 ...
- HDU 4686 矩阵快速幂 Arc of Dream
由式子的性质发现都是线性的,考虑构造矩阵,先有式子,a[i] = ax * a[i-1] + ay; b[i] = bx*b[i-1] +by; a[i]*b[i] = ax*bx*a[i-1]*b[ ...
- HDU - 1575——矩阵快速幂问题
HDU - 1575 题目: A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n( ...
随机推荐
- C++ MOOC
相关课程列表: C++远征之起航篇 C++远征之离港篇 C++远征之封装篇 上 C++远征之封装篇 下 C++远征之继承篇 C++远征之多态篇 授课老师:james_yuan 在寒假,我主要选择 C+ ...
- golang string转json的一些坑
先带来点冷知识,不知道大家知不知道,反正我刚知道... 大佬们都知道怎么在string中给string类型赋值带双引号的字符串,没错就是用反斜杠,如下: msg := "{\"na ...
- properties文件读取与写入
将peoperties文件的读取和写入封装成了一个工具类: import java.io.BufferedInputStream; import java.io.FileInputStream; im ...
- BZOJ5125 小Q的书架(决策单调性+动态规划+分治+树状数组)
设f[i][j]为前i个划成j段的最小代价,枚举上个划分点转移.容易想到这个dp有决策单调性,感性证明一下比较显然.如果用单调栈维护决策就不太能快速的求出逆序对个数了,改为使用分治,移动端点时树状数组 ...
- python selenium2 定位一组元素find_elements实例
打开hao123首页,需要定位以上区域中的所有链接,他们有相同的父元素<ul class="js_bd site-bd site-hd0">,所有链接处在li>a ...
- java 自动装箱
Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),相当于调用包装类的valueof方法.举例说明: 源码: 编译之后的代码:
- Ubuntu实用软件安装[转]
Gedit编辑器配置 Ubuntu14.04从安装软件到卸载软件,删除安装包 linux wget 命令用法详解(附实例说明) ==================================== ...
- 【BZOJ3064】CPU监控(线段树)
[BZOJ3064]CPU监控(线段树) 题面 BZOJ 洛谷 题解 神仙\(zsy\)出在了\(noip\)模拟的题目.(然而\(zsy\)出的还是这题的升级版) 首先明确一点,这题是一个吉司机线段 ...
- 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)
[CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...
- BZOJ3601 一个人的数论 【数论 + 高斯消元】
题目链接 BZOJ3601 题解 挺神的 首先有 \[ \begin{aligned} f(n) &= \sum\limits_{x = 1}^{n} x^{d} [(x,n) = 1] \\ ...