前言

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

题意

求 \((\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;
}

P5137 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. netstat命令输出详解

    netstat命令输出详解 1. 列出所有的TCP和UDP端口 2. 命令输出详解 Proto:协议名(tcp协议还是udp协议) recv-Q:网络接收队列,send-Q:网路发送队列 a. rec ...

  2. Harry Potter RPG_1

    RPG--Harry Potter 博主最近迷上了<Harry Potter> So 我制作了一款RPG对话模拟游戏, 目前主线以进行到了分院以后: 有兴趣的小伙伴可以看看,能点个关注就更 ...

  3. 教育法学期末考试02MOOC

    期末考试 返回 期末考试试卷为客观题,总分为100分,占课程成绩的40%.其中包含16道单选题,2道多选题.共18道题.单选题每道5分,多选题每道10分,限时90分钟完成.  倒计时:  01:21: ...

  4. WPF 中引入依赖注入(.NET 通用主机)

    WPF 中引入依赖注入(.NET 通用主机) 在网上看到的文章都是通过 App.cs 中修改配置进行的,这样侵入性很高而且服务主机是通过 App 启动时加载的而不是服务主机加载的 App 有一点违反原 ...

  5. 从零用VitePress搭建博客教程(4) – 如何自定义首页布局和主题样式修改?

    接上一节:从零用VitePress搭建博客教程(3) - VitePress页脚.标题logo.最后更新时间等相关细节配置 六.首页样式修改 有时候觉得自带的样式不好看,想自定义,首先我们在docs/ ...

  6. 文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题

    三.用go语言,在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中,为什么不需要设置或重置对象的 prev 属性呢? 文心一言: 在 Go 语言中,ALLOCATE-OBJECT ...

  7. 掌握 Kubernetes 故障排除:有效维护集群的最佳实践和工具

    Kubernetes 是一款管理容器化应用程序的强大工具.然而,与任何复杂的系统一样,使用它时也可能出错.当问题出现时, 掌握有效的故障排除技术和工具非常重要. 本文将介绍以下步骤,助您了解事件收集的 ...

  8. Chromium Canvas工作流

    blink 中实现了2种 canvas,分别是 blink::HTMLCanvasElement 和 blink::OffscreenCanvas ,前者对应 html/dom 中的 canvas,后 ...

  9. Net 高级调试之四:Windbg 动态调试

    一.简介 今天是<Net 高级调试>的第四篇文章.到今天为止,也有三篇文章了,对 Windbg 也有初步的认识了,当然,一个工具流畅.熟练的使用,对于我们调试 Net 程序是至关重要的.在 ...

  10. 一、docker的安装及docker-compose安装

    一. 安装docker 1.1安装 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # https://get.d ...