codeforces 1182F 矩阵快速幂

题意:设f(n) = c ^ (2n - 6) * f(n - 1) * f(n - 2) * f(n - 3), 问第n项是多少?

思路:官方题解:我们先转化一下,令g(x) =  c ^ x * f(x), 那么原式转化为了g(x) = g(x - 1) * g(x - 2) * g(x - 3)。之后我们可以考虑把f(1), f(2), f(3)和c的质因子找出来,枚举质因子对答案的贡献。我们发现,如果是质因子的数目的话,乘法就变成了加法(相当于统计质因子的指数),这样就可以用矩阵乘法优化了。注意,矩阵转移的时候,模数是1e9 + 6,因为转移的时候是指数(欧拉定理)。其实基于这种想法,我们可以不用处理质因子,直接计算g(1), g(2),g(3)对答案的贡献。

代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod = 1e9 + 7;
const LL mod1 = 1e9 + 6;
map<LL, LL> mp[4];
set<LL> s;
set<LL>::iterator it;
struct Matrix {
	LL a[3][3];

	void init(LL num = 0) {
		memset(a, 0, sizeof(a));
		for (int i = 0; i < 3; i++)
			a[i][i] = num;
	}

	Matrix operator * (const Matrix& now) const {
		Matrix res;
		res.init();
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				for (int k = 0; k < 3; k++)
					res.a[i][j] = (res.a[i][j] + (a[i][k] * now.a[k][j]) % mod1) % mod1;
		return res;
	}

	Matrix operator ^ (const LL num) const {
		Matrix ans, x = *this;
		ans.init(1);
		LL now = num;
		for (; now; now >>= 1) {
			if(now & 1) ans = ans * x;
			x = x * x;
		}
		return ans;
	}

	void print() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				printf("%lld ", a[i][j]);
			}
			printf("\n");
		}

	}
};
void div(LL num, int pos) {
	for (LL i = 2; i * i <= num; i++) {
		if(num % i == 0) {
			s.insert(i);
			while(num % i == 0) {
				mp[pos][i]++;
				num /= i;
			}
		}
	}
	if(num > 1) {
		s.insert(num);
		mp[pos][num]++;
	}
}
LL qpow(LL x, LL y) {
	LL ans = 1;
	for (; y; y >>= 1ll) {
		if(y & 1ll) ans = (ans * x) % mod;
		x = (x * x) % mod;
	}
	return ans;
}
LL a[4];
int main() {
	LL n;
	scanf("%lld", &n);
	for (int i = 0; i < 4; i++) {
		scanf("%lld", &a[i]);
		div(a[i], i);
	}
	Matrix x, y, x1;
	x.init();
	x.a[0][2] = x.a[1][2] = x.a[2][2] = x.a[2][1] = x.a[1][0] = 1;
	x = x ^ (n - 1);
	LL ans = 1;
	for (it = s.begin(); it != s.end(); it++) {
		y.init();
		for (int i = 0; i < 3; i++) {
			y.a[0][i] = mp[i][*it];
		}
		for (int i = 0; i < 3; i++)
			y.a[0][i] = (y.a[0][i] + ((LL)(i + 1) * mp[3][*it] % mod)) % mod;
		y = y * x;
		ans = (ans * qpow(*it, y.a[0][0]) % mod) % mod;
	}
	ans = ans * qpow(qpow(a[3], mod - 2), n) % mod;
	printf("%lld\n", ans);
}

  

原文地址:https://www.cnblogs.com/pkgunboat/p/11012730.html

时间: 2024-08-26 04:40:27

codeforces 1182F 矩阵快速幂的相关文章

Xor-sequences CodeForces - 691E || 矩阵快速幂

Xor-sequences CodeForces - 691E 题意:在有n个数的数列中选k个数(可以重复选,可以不按顺序)形成一个数列,使得任意相邻两个数异或的结果转换成二进制后其中1的个数是三的倍数.求可能形成的不同数列个数(只要选出的数列中,任意两个元素在原序列中的位置不同,就算作不同的序列,比如在原数列[1,1]中选1个,那么第一个1和第二个1要分开算). 方法: 很容易列出dp方程: dp[k][i]表示取了k个,最后一个在第i位.a[i][j]表示i和j异或结果转换成二进制后1的个数

codeforces 185a(矩阵快速幂)

题意:三角形变化过程如下图 问正着的三角形的个数,n=1时1个,n=2时3个,n=3时10 - . 题解:可以找到规律 正x 倒y 1 0 3 1 10 6 - - 3*x+y 3*y+x 然后构造矩阵用矩阵快速幂求解. #include <cstdio> #include <iostream> #include <cstring> using namespace std; const int MOD = 1000000007; const int N = 3; str

【矩阵快速幂 】Codeforces 450B - Jzzhu and Sequences (公式转化)

[题目链接]click here~~ [题目大意] Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn modulo1000000007(109?+?7). [解题思路] /*A - Jzzhu and Sequences Codeforces 450B - Jzzhu and Sequences ( 矩阵快速幂 )

Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)

题目链接:http://codeforces.com/problemset/problem/450/B 题意很好懂,矩阵快速幂模版题. 1 /* 2 | 1, -1 | | fn | 3 | 1, 0 | | fn-1 | 4 */ 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 using namespace std; 9 typedef __int64 LL; 10 LL mod =

CodeForces 185A. Plant(矩阵快速幂)

题目链接:http://codeforces.com/problemset/problem/185/A Dwarfs have planted a very interesting plant, which is a triangle directed "upwards". This plant has an amusing feature. After one year a triangle plant directed "upwards" divides int

[递推+矩阵快速幂]Codeforces 1117D - Magic Gems

传送门:Educational Codeforces Round 60 – D 题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem,现在需要N个gem,可以选择一定的magic gem,指定每一个分裂或不分裂,问一共有多少种方案 两种分裂方案不同当且仅当magic gem的数量不同,或者分裂的magic gem的索引不同. 思路: 1.首先从dp的角度出发 设F(i)为最终需要i个gem的方案数,容易得到递推式: (总方案数 = 最右边的m

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

codeforces 678D Iterated Linear Function 矩阵快速幂

矩阵快速幂的题要多做 由题可得 g[n]=A*g[n-1]+B 所以构造矩阵  { g[n] }    =  {A   B}  * { g[n-1]} {   1   }         {0   1}     {    1    } 然后矩阵快速幂就好 矩阵快速幂的题要多做,多构造矩阵 注:其实这个题可以直接等比数列求求和,单数矩阵快速幂对于这类题更具有普遍性 #include <cstdio> #include <iostream> #include <ctime>

Codeforces 450B div.2 Jzzhu and Sequences 矩阵快速幂or规律

Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn modulo 1000000007 (109 + 7). Input The first line contains two integers x and y (|x|, |y| ≤ 109). The second line contains a single i