多项式求根
题目链接:NOI2022省选挑战赛 Contest10 A
题目大意
给你 x+y,xy % 998244343 的值,要你求 x^n+y^n % 998244353 的值。
思路
考虑从
x
n
−
1
+
y
n
−
1
x^{n-1}+y^{n-1}
xn−1+yn−1 推出
x
n
+
y
n
x^n+y^n
xn+yn:
(
x
n
−
1
+
y
n
−
1
)
(
x
+
y
)
=
x
n
+
x
n
−
1
y
+
y
n
−
1
x
+
y
n
(x^{n-1}+y^{n-1})(x+y)=x^n+x^{n-1}y+y^{n-1}x+y^n
(xn−1+yn−1)(x+y)=xn+xn−1y+yn−1x+yn
(
x
n
−
1
+
y
n
−
1
)
(
x
+
y
)
=
x
n
+
y
n
+
x
y
(
x
n
−
2
+
y
n
−
2
)
(x^{n-1}+y^{n-1})(x+y)=x^n+y^n+xy(x^{n-2}+y^{n-2})
(xn−1+yn−1)(x+y)=xn+yn+xy(xn−2+yn−2)
x
n
+
y
n
=
(
x
n
−
1
+
y
n
−
1
)
(
x
+
y
)
−
x
y
(
x
n
−
2
+
y
n
−
2
)
x^n+y^n=(x^{n-1}+y^{n-1})(x+y)-xy(x^{n-2}+y^{n-2})
xn+yn=(xn−1+yn−1)(x+y)−xy(xn−2+yn−2)
设
x
i
+
y
i
=
f
i
,
(
x
+
y
)
=
a
,
x
y
=
b
x^i+y^i=f_i,(x+y)=a,xy=b
xi+yi=fi,(x+y)=a,xy=b
f
n
=
a
f
n
−
1
−
b
f
n
−
2
f_n=af_{n-1}-bf_{n-2}
fn=afn−1−bfn−2
然后就可以用矩阵乘法来做啦!
代码
#include<cstdio>
#define ll long long
#define mo 998244353
using namespace std;
ll a, b, n;
struct matrix {
ll n, m, a[3][3];
}A, B, C, one;
matrix operator *(matrix x, matrix y) {
matrix re;
re.n = x.n; re.m = y.m;
for (int i = 1; i <= re.n; i++)
for (int j = 1; j <= re.m; j++)
re.a[i][j] = 0;
for (int k = 1; k <= x.m; k++)
for (int i = 1; i <= re.n; i++)
for (int j = 1; j <= re.m; j++)
(re.a[i][j] += x.a[i][k] * y.a[k][j] % mo) %= mo;
return re;
}
matrix jcksm(matrix x, ll y) {
matrix re = one;
while (y) {
if (y & 1) re = re * x;
x = x * x; y >>= 1;
}
return re;
}
int main() {
scanf("%lld %lld %lld", &a, &b, &n);
A.n = 1; A.m = 2;
A.a[1][1] = 2; A.a[1][2] = a;
B.n = 2; B.m = 2;
B.a[1][1] = 0; B.a[1][2] = mo - b;
B.a[2][1] = 1; B.a[2][2] = a;
one.n = 2; one.m = 2;
one.a[1][1] = 1; one.a[1][2] = 0;
one.a[2][1] = 0; one.a[2][2] = 1;
C = jcksm(B, n - 1);
A = A * C;
printf("%lld", A.a[1][2]);
return 0;
}