【NOI2022省选挑战赛 Contest10 A】多项式求根(矩阵乘法)
多项式求根
题目链接:NOI2022省选挑战赛 Contest10 A
题目大意
给你 x+y,xy % 998244343 的值,要你求 x^n+y^n % 998244353 的值。
思路
考虑从 \(x^{n-1}+y^{n-1}\) 推出 \(x^n+y^n\):
\((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+y^n+xy(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})\)
设 \(x^i+y^i=f_i,(x+y)=a,xy=b\)
\(f_n=af_{n-1}-bf_{n-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;
}

浙公网安备 33010602011771号