首页 > 其他分享 >P5137 题解

P5137 题解

时间:2022-12-28 12:33:23浏览次数:62  
标签:ch 题解 sum 矩阵 bmatrix P5137 include 乘法

前言

首先感谢所有帮助我卡常的大佬们。

题意

求 \((\sum_{i = 0}^{n} a^i b^{n - i})\mod p\) 的值(\(n \leq 10^{18}\),\(p\) 不一定为质数)。

分析

看到数据范围,首先想到快速幂 \(+\) 乘法逆元或者矩阵乘法。

但是看到 \(p\) 不为质数,那就只有可能是矩阵乘法了。

设 \(S_n = \sum_{i = 0}^{n} a^i b^{n - i}\),

则有 \(S_{n + 1} = \sum_{i = 0}^{n} a^ib^{n + 1 - i} + a^{n + 1}b^0 = b \sum_{i = 0}^{n} a^ib^{n - i} + a^{n + 1} = S_{n} \times b + a^{n + 1}\)。

有了递推式,我们就可以设出矩阵。

设向量 \(\begin{bmatrix} S_n & a^n \end{bmatrix}\),则有如下等式:

\[\begin{bmatrix} S_n & a^n \end{bmatrix} \times \begin{bmatrix} b & 0 \\ a & a \end{bmatrix} = \begin{bmatrix} S_{n + 1} & a^{n + 1} \end{bmatrix}\]

矩阵乘法不会的点这里矩阵乘法

剩下的就交给矩阵快速幂了。

几个注意事项:

  1. 两个 long long 相乘会爆,要用 __int128
  2. 矩阵乘法要展开循环。否则会超时。
  3. 一定要快读快写!!

代码示例

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

#define LL long long
#define PII pair<int, int>
#define PLL pair<LL, LL>
#define Int __int128

LL T;
Int ans[2], t[2][2];

namespace FastIO {
	char buf[1 << 21], *_now = buf, *_end = buf;
	#define getchar() (_now == _end && (_end = (_now = buf) + fread(buf, 1, 1 << 20, stdin), _now == _end) ? EOF : *_now ++  )
	void read() { return; }
	template <typename T, typename ...T2>
	void read(T &s, T2 &...oth) {
		s = 0; int f = 1; char ch = getchar();
		for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = ~f + 1;
		for (; ch >= '0' && ch <= '9'; ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48);
		s *= f; read(oth...); return;
	}
	void write() { return; }
	template <typename T, typename ...T2>
	void write(T s, T2 ...oth) {
		if (s == 0) { putchar('0'), putchar('\n'); write(oth...); return; }
		int stk[100], top = 0;
		if (s < 0) putchar('-'), s = ~s + 1;
		while (s) stk[ ++ top] = s % 10, s /= 10;
		do putchar(stk[top -- ] + (1 << 4) + (1 << 5)); while (top);
		putchar('\n'); write(oth...); return;
	}
}
#define read FastIO::read
#define write FastIO::write
#define Inline __inline__ __attribute__((always_inline))

Inline void mul(Int ans[], Int a[], Int b[][2], LL p) 
{
    Int tmp[2] = {0};
    tmp[0] = (tmp[0] + (Int)a[0] * b[0][0]) % p;
	tmp[0] = (tmp[0] + (Int)a[1] * b[1][0]) % p;
	tmp[1] = (tmp[1] + (Int)a[0] * b[0][1]) % p;
	tmp[1] = (tmp[1] + (Int)a[1] * b[1][1]) % p;
    memcpy(ans, tmp, sizeof tmp);
}

Inline void mul(Int ans[][2], Int a[][2], Int b[][2], LL p) {
    Int tmp[2][2] = {0};
    tmp[0][0] = (tmp[0][0] + (Int)a[0][0] * b[0][0]) % p;
	tmp[0][0] = (tmp[0][0] + (Int)a[0][1] * b[1][0]) % p;
	tmp[0][1] = (tmp[0][1] + (Int)a[0][0] * b[0][1]) % p;
	tmp[0][1] = (tmp[0][1] + (Int)a[0][1] * b[1][1]) % p;
	tmp[1][0] = (tmp[1][0] + (Int)a[1][0] * b[0][0]) % p;
	tmp[1][0] = (tmp[1][0] + (Int)a[1][1] * b[1][0]) % p;
	tmp[1][1] = (tmp[1][1] + (Int)a[1][0] * b[0][1]) % p;
	tmp[1][1] = (tmp[1][1] + (Int)a[1][1] * b[1][1]) % p;
    memcpy(ans, tmp, sizeof tmp);
}

Inline void solve(LL a, LL b, LL n, LL p) {
    ans[0] = 1, ans[1] = 1;
    t[0][0] = b, t[0][1] = 0, t[1][0] = a, t[1][1] = a;
    while (n) {
        if (n & 1) mul(ans, ans, t, p);
        mul(t, t, t, p); n >>= 1;
    }
    write(ans[0]);
}

int main() {
    read(T);
    while (T--) {
        LL n, a, b, p;
        read(n, a, b, p);
        solve(a, b, n, p);
    }

    return 0;
}

标签:ch,题解,sum,矩阵,bmatrix,P5137,include,乘法
From: https://www.cnblogs.com/LcyRegister/p/17009879.html

相关文章

  • C#提示指定的路径或文件名太长问题解决办法
    我用的是.net4.0的环境,直接在app.config配置文件中加几行配置就行。如下图:<configuration><runtime><AppContextSwitchOverridesvalue="Switch.System.IO.......
  • SEERC2022 D Divisible by 4 Spanning Tree 题解
    题意给定\(n\)个点\(m\)条边的无向连通图,判断是否有存在生成树满足:度数为奇数的点个数为\(4\)的倍数。\(1\len\le200000,1\lem\le400000\)题解度数总和是\(2n......
  • 【题解】P5298 [PKUWC2018]Minimax
    P5298[PKUWC2018]Minimax思路线段树合并优化树形dp.值域1e9首先考虑离散化。然后发现需要维护每种权值的出现概率,于是可以考虑到一个简单的树形dp:设\(f[i][j]\)......
  • 问题解决:Failed to download metadata for repo ‘appstream‘: Cannot prepare inter
    https://cloud.tencent.com/developer/article/1993317 大家都知道Centos8于2021年年底停止了服务,大家再在使用yum源安装时候,出现下面错误“错误:Failedtodownloadmet......
  • 快速幂 矩阵快速幂题解
    目录快速幂矩阵快速幂练习题题解12.28HDU1061HDU1575HDU2035HDU5015HDU6198快速幂矩阵快速幂练习题题解12.28HDU1061题意:给定T组数据,接下来T行有T个数,求N的N次......
  • CodeForces-690#D1 题解
    正文很显然啊,这是在考一个叫连通块的东东,于是蒟蒻的我马上想到了连通块必备:并查集。如果一个块四边连通了其它的块,那么合并这两个块。当然,并查集要用二维的:typedefpai......
  • 【题解】1059: 贴瓷砖
    1059:贴瓷砖题目描述有一块大小是2*n的墙面,现在需要用2种规格的瓷砖铺满,瓷砖规格分别是2*1和2*2,请计算一共有多少种铺设的方法。输入输入的第一行包含一个......
  • P6357 题解
    Luogu题面题目描述给定一串长度为\(n\)的数字,数字为\(0\sim9\)之间的任意一个,下标从\(1\)记起。然后进行\(m\)次区间查询,每次查找区间\([l,r]\)的区间和,......
  • answerOpenCV轮廓类问题解析
    contour在opencv中是一个基础的数据结构,灵活运用的话,作用很大。以contour为关键字,在answerOpenCV中能够发现很多有趣的东西。 1、无法解决的问题​​......
  • 【题解】ABC283
    \(\text{AtCoderBeginnerContest283}\)APower无意义题,直接输出。BFirstQueryProblem无意义题,维护一个支持单点修改、单点查询的数据结构。(雾)CCashRegister......