2017 ACM-ICPC 西安赛区 网络赛 F. Trig Function 【规律题】

来源:互联网 发布:淘宝铝合金箱子 编辑:程序博客网 时间:2024/06/18 09:17


Trig Function

TimeLimit: 2000/1000 MS (Java/Others)    Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 714    Accepted Submission(s): 206

Problem Description

f(cos(x))=cos(n∗x) holds for all x.

Given two integersn and m , you need to calculate the coefficient of x^m​​ in f(x), modulo 998244353

  

Input

Multiple testcases (no more than 100).

Each test casecontains one line consisting of two integers n and m.

1≤n≤109,0≤m≤104

  

Output

Output the answerin a single line for each test case.

  

Sample Input

2 0

2 1

2 2

 

Sample Output

998244352

0

2



【题意】


给出一个函数,代入n,m后求出xm的系数,并取膜输出。


【思路】


我们先尝试把cos(nx)化为cos(x)的形式,然后把cos(x)用x代换,就可以得到f(x)=...的形式,然后就能得到所求的系数了。


那么我们如何把cos(nx)化为cos(x)的形式呢。


其实可以尝试着暴力写出前几项的形式。如下图:


由写出的式子,我们可以发现以下几点:


  1. 当m大于n时,答案显然为0。
  2. 当n为奇数且m为偶数或n为偶数且m为奇数时答案显然为0。
  3. 当n为奇数,且m为1时,答案的绝对值为n。
  4. 当n为偶数,且m为0时,答案的绝对值为1。
  5. 其余情况答案的绝对值均为【 n * (n-m+2) * (n-m+4) * ... * (n+m-4) * (n+m-2) 】/(m!)。(注意逆元的运用)
  6. 上面出现绝对值的情况,3和4 当(n/2)%2 == 0 时符号为正,否则为负;5 当((n-m)/2)%2 == 0时,符号为正,否则符号为负。


依照这个规律分类讨论一下即可。


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100005;const ll mod = 998244353;const int INF = 0x3f3f3f3f;const double eps = 1e-9;int n,m;int a[maxn];ll fast_mod(ll a,ll b,ll Mod){    ll ans=1;    a%=Mod;    while(b)    {        if(b&1)            ans=(ans*a)%Mod;        b>>=1;        a=(a*a)%Mod;    }    return ans;}ll solve(ll n,ll m){    if(n&1)    {        if(m%2==0) return 0;        if(m==1)        {            if((n/2)%2==0) return n;            return -n;        }    }    else    {        if(m&1) return 0;        if(m==0)        {            if((n/2)%2==0) return 1;            return -1;        }    }    ll ans=1;    for (int i=n-m+2; i<=n+m-2; i+=2)    {        ans=(ans*i)%mod;    }    ans=(ans*n)%mod;    ll temp=1;    for(int i=1;i<=m;i++)    {        temp=(temp*i)%mod;    }    ans=(ans*fast_mod(temp,mod-2,mod))%mod;  //求逆元    int flag=(((n-m)/2)%2==0)?1:-1;    return flag*ans;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        if(m>n)        {            puts("0");            continue;        }        ll ans=solve(n,m);        ans=(ans+mod)%mod;        printf("%lld\n",ans);    }    return 0;}






阅读全文
0 0