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

来源:互联网 发布:hdmi网络高清传输器tx 编辑:程序博客网 时间:2024/06/05 00:33

题目链接:https://nanti.jisuanke.com/t/17119

题目大意:f(cos(x))=cos(n∗x) ,把化成f(t)的多项式后,求对应m次方前面的系数

参考链接:https://en.wikipedia.org/wiki/Chebyshev_polynomials

解题思路:用到了切比雪夫多项式的知识,虽然我看不懂递推结果是怎么出来的,但是递推过程我还是能解释一下的cos(n*x)=cos((n-1)*x+x)=cos((n-1)*x)*cos(x)-sin((n-1)*x)*sinx=cos((n-2)*x)*cos(x)*cos(x)-2*sin(x)*cos(x)*sin((n-2)*x)-cos((n-2)*x)*sin(x)*sin(x)=2*cos((n-2)*x)*cos(x)*cos(x)-2*sin(x)*cos(x)*sin((n-2)*x)-cos((n-2)*x)=2*cos(x)*cos((n-1)*x)-cos((n-2)*x),所以递推式为F(n)=2*t*F(n-1)-F(n-2),递推式的通项式:
这里写图片描述
所以系数就是n/2*(-1)^k*C(n-k,k)/(n-k)*2^(n-2*k),要注意这里的k不是m,然后由于n,m过大,求C(n-k,k)可以用Lucas定理加速

AC代码:

#include<cstdio>  #include<algorithm>using namespace std;typedef long long LL;const LL p = 998244353;LL quick_mod(LL a, LL b){    LL ans = 1;    a %= p;    while (b)    {        if (b & 1)            ans = ans * a % p;        b >>= 1;        a = a * a % p;    }    return ans;}LL C(LL n, LL m){    if (m > n) return 0;    LL ans = 1;    m = min(m, n - m);    for (int i = 1; i <= m; i++)    {        LL a = (n - i + 1) % p;        LL b = i % p;        ans = ans * (a * quick_mod(b, p - 2) % p) % p;    }    return ans;}LL Lucas(LL n, LL m){    if (m == 0) return 1;    return C(n % p, m % p) * Lucas(n / p, m / p) % p;}int main(){    for (int n, m;scanf("%d%d", &n, &m) == 2;)    {        if (n % 2 != m % 2||m>n)            puts("0");        else        {            int k = (n - m) / 2;            LL ans = n%p*quick_mod(2, p - 2) % p;            ans *= quick_mod(2, n - 2 * k), ans %= p;            ans *= quick_mod(n - k, p - 2), ans %= p;            ans *= Lucas(n - k, k), ans %= p;            if (k % 2)                ans = -ans;            int tmp = (ans + p) % p;            printf("%d\n", tmp);        }    }    return 0;}
阅读全文
0 0
原创粉丝点击