本文在此处同步更新
题目
样例
4
2 3 100
1 4 1000
3 3 1000000000
9 123456 78987
54
4
299
12153
首先我们可以推出如下式子
-
a n = x a n − 1 + y a n − 2 a_n=xa_{n-1}+ya_{n-2} an=xan−1+yan−2
-
a n 2 = x 2 a n − 1 2 + 2 x y a n − 1 a n − 2 + y 2 a n − 2 2 a_n^2=x^2 a_{n-1}^2+2xya_{n-1}a_{n-2}+y^2a_{n-2}^2 an2=x2an−12+2xyan−1an−2+y2an−22
-
s n = s n − 1 + a n 2 s_{n}=s_{n-1}+a_n^2 sn=sn−1+an2
然后发现,要求 s n s_{n} sn,先要知道 a n 2 a_n^2 an2,要知道 a n 2 a_n^2 an2,还要知道 a n − 1 a n − 2 a_{n-1}a_{n-2} an−1an−2
虽然我们可以先求出 s n s_{n} sn与 a n 2 a_n^2 an2以及 a n + 1 2 a_{n+1}^2 an+12(前2个都告诉你了),可 a n + 2 a_{n+2} an+2呢?
那就得知道 a n a n + 1 a_na_{n+1} anan+1了
可得 a n a n + 1 = a n ( x a n + y a n − 1 ) = x a n 2 + y a n a n − 1 a_na_{n+1}=a_n(xa_n+ya_{n-1})=xa_{n}^2+ya_{n}a_{n-1} anan+1=an(xan+yan−1)=xan2+yanan−1
a n 2 a_{n}^2 an2已知
a n a n − 1 a_{n}a_{n-1} anan−1可以通过同样的式子(除了初始化时,不过那可以直接算)求出来
于是我们知道了怎么构造
a
n
s
ans
ans矩阵
{
s
[
n
−
1
]
,
a
1
a
[
n
]
2
,
a
2
a
[
n
−
1
]
2
,
a
3
a
[
n
]
∗
a
[
n
−
1
]
a
4
}
\{\\ s[n-1], a1 \\ a[n]^2, a2 \\ a[n-1]^2, a3 \\ a[n]*a[n-1] a4 \\ \}
{s[n−1],a1a[n]2,a2a[n−1]2,a3a[n]∗a[n−1]a4}
至于
b
a
s
e
base
base矩阵,可以直接根据上面的算
第一项可以直接加法得到,第三项则直接由原来第二项变换过来
第二、第四项的简化式子如下
a
[
n
+
1
]
2
=
x
2
∗
a
2
+
y
2
∗
a
3
+
2
x
y
∗
a
4
a[n+1]^2=x^2*a2+y^2*a3+2xy*a4
a[n+1]2=x2∗a2+y2∗a3+2xy∗a4
a
[
n
]
a
[
n
+
1
]
=
x
∗
a
[
n
]
2
+
y
∗
a
[
n
]
∗
a
[
n
−
1
]
=
x
∗
a
2
+
y
∗
a
4
a[n]a[n+1]=x*a[n]^2+y*a[n]*a[n-1]=x*a2+y*a4
a[n]a[n+1]=x∗a[n]2+y∗a[n]∗a[n−1]=x∗a2+y∗a4
可得
b
a
s
e
base
base为
{
1
1
0
0
0
x
2
y
2
2
x
y
0
1
0
0
0
x
0
y
}
\{\\ 1~~~1~~~0~~~0\\ 0~x^2~y^2~2xy\\ 0~~~1~~~0~~~0\\ 0~~~x~~~0~~~y\\ \}
{1 1 0 00 x2 y2 2xy0 1 0 00 x 0 y}
剩下的主要是预处理与快速幂
还有 不开long long见祖宗
所有预处理记得都取模一下,不然 long long会炸
快速幂有点烦,其他还好
//写得有些丑,见谅
#pragma GCC optimize(1, "inline", "Ofast")
#pragma GCC optimize(2, "inline", "Ofast")
#pragma GCC optimize(3, "inline", "Ofast")
// #include <bits/extc++.h>
#include <bits/stdc++.h>
#define memery() std::cerr << "The memory is " << (&ed - &st) / 1024.0 / 1024 << "MB." << std::endl
//#include <"C:\Users\admin\Documents\myhead\fstio.hpp">
//#include <"C:\Users\admin\Documents\myhead\def.hpp">
//#include <"C:\Users\admin\Documents\myhead\help.h">
// using namespace __gnu_cxx;
// using namespace __gnu_pbds;
using namespace std;
#define int long long
//变量区
bool st;
const int N = 5e6 + 7;
//please write sth.
int tk, a[4][4], b[4][4], c[4][4], n, m, x;
bool ed;
//函数区
void input()
{
//please write sth.
cin >> x >> n >> m;
}
void mul1(int b[4][4])
{
//5 4
for (int i = 0; i < 4; i++)
for (int j = 0; j < 1; j++)
c[i][j] = 0;
for (int k = 0; k < 4; k++)
for (int i = 0; i < 4; i++) //0 0 0 x x 0
for (int j = 0; j < 1; j++)
(c[i][j] += ((1ll * b[i][k] * a[k][j]) % m + m) % m) %= m;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 1; j++)
a[i][j] = c[i][j];
}
void mul2(int a[4][4], int b[4][4], int c[4][4])
{
//5 4
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
c[i][j] = 0;
for (int k = 0; k < 4; k++)
for (int i = 0; i < 4; i++) //0 0 0 x x 0
for (int j = 0; j < 4; j++)
(c[i][j] += ((1ll * a[i][k] * b[k][j]) % m + m) % m) %= m;
}
void k(int a[4][4], int b[4][4])
{
int xx[4][4];
mul2(a, b, xx);
for (int i = 0; i < 4; i++) //0 0 0 x x 0
for (int j = 0; j < 4; j++)
a[i][j] = xx[i][j];
}
void work()
{
//please write sth.
a[0][0] = 1;
a[1][0] = (1ll * x * x) % m;
a[2][0] = 1;
a[3][0] = x;
x *= 2, x %= m;
int y = -1;
int bb[4][4] = { { 1, 1, 0, 0 },
{ 0, (1ll * x * x) % m, (1ll * y * y) % m, (2ll * x * y) % m },
{ 0, 1, 0, 0 },
{ 0, x, 0, y } };
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
b[i][j] = bb[i][j];
n--;
for (; n; n >>= 1, k(b, b))
if (n & 1)
mul1(b);
}
void output()
{
//please write sth.
if (n == 1)
cout << 1 << endl;
else
cout << a[0][0] << endl;
}
//主函数
signed main()
{
//memory();
std::ios::sync_with_stdio(0);
std::cin.tie(), std::cout.tie();
cin >> tk;
while (tk--) {
input();
work();
output();
}
}