Trig Function 2017ACM-ICPC亚洲区(西安赛区)网络赛F题

来源:互联网 发布:java web 工作流引擎 编辑:程序博客网 时间:2024/06/05 03:31

题意:题目中的 f(cos(x))=cos(nx) 可以展开成 cos(x) 的多项式,即f(x) 可以展开成 x 的多项式,给定 n 和 x 的指数 m,让我们求 xm 的系数模998244353的结果。

思路:做的时候上网查了下将 cos(nx) 展开成 cos(x) 的多项式的公式,于是乎查到了这个,叫切比雪夫多项式:
这里写图片描述
上面的 !! 表示的是双阶乘,双阶乘计算时只乘以与原数本身奇偶性相同的数,如 10!!=10×8×6×4×29!!=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;}
阅读全文
0 0
原创粉丝点击