题意:题目中的
f(cos(x))=cos(n∗x)
可以展开成
cos(x)
的多项式,即
f(x)
可以展开成
x
的多项式,给定 n 和 x 的指数 m,让我们求
思路:做的时候上网查了下将
cos(n∗x)
展开成
cos(x)
的多项式的公式,于是乎查到了这个,叫切比雪夫多项式:
上面的
!!
表示的是双阶乘,双阶乘计算时只乘以与原数本身奇偶性相同的数,如
10!!=10×8×6×4×2
,
9!!=9×7×5×3×1
。其中规定
0!!=1
。
对于这个公式,
当 n 为偶数 m 为奇数时系数为 0,当 n 为奇数 m 为偶数时系数为 0;
其他情况下,注意乘法逆元的使用,同时分子部分的双阶乘和分母部分的双阶乘可以进行约分。约分时,n 为偶数 k 为 0 时特殊, n 为奇数 k 为 1 时特殊,自己讨论下具体情况就知道啦。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD = 998244353;
int n,m;
LL Pow(LL x,LL n)
{
LL ret=1;
LL temp=x;
while(n!=0)
{
if(n&1)
ret=(ret*temp)%MOD;
n>>=1;
temp=(temp*temp)%MOD;
}
return ret;
}
LL JC(LL a)
{
LL ans = 1;
for(LL i=2; i<=a; i++) ans = (i*ans) %MOD;
return ans;
}
LL DJC(LL s, LL e)
{
LL ans = 1;
for(LL i=e; i>=s; i-=2) ans = (i*ans) %MOD;
return ans;
}
int main()
{
while(scanf("%d%d", &n, &m) == 2){
int k;
if(n%2 == 0){ //n 为偶数的情况
if(m%2 == 1) printf("0\n"); //m 为奇数
else{
k = m/2;
LL subans1 = (n*Pow(JC(2*k), MOD-2)) %MOD;
LL subans2;
if(k == 0){
subans2 = (Pow(n, MOD-2)) %MOD;
}
else{
subans2 = (DJC(n-2*k+2, n+2*k-2)) %MOD;
}
LL ans = (subans1*subans2) %MOD;
if(((n-2*k)/2) %2 !=0) ans = -ans;
printf("%lld\n", (ans+MOD)%MOD);
}
}
else{ //n 为奇数的情况
if(m%2 == 0) printf("0\n"); //m 为偶数
else{
k = m/2+1;
LL subans1 = (n*Pow(JC(2*k-1),MOD-2)) %MOD;
LL subans2;
if(k == 1){
subans2 = 1;
}
else{
subans2 = (DJC(n+1-2*k+2,n+2*k-3)) %MOD;
}
LL ans = (subans1*subans2) %MOD;
if(((n+1-2*k)/2) %2 !=0) ans = -ans;
printf("%lld\n", (ans+MOD)%MOD);
}
}
}
return 0;
}