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)的形式呢。
其实可以尝试着暴力写出前几项的形式。如下图:
由写出的式子,我们可以发现以下几点:
- 当m大于n时,答案显然为0。
- 当n为奇数且m为偶数或n为偶数且m为奇数时答案显然为0。
- 当n为奇数,且m为1时,答案的绝对值为n。
- 当n为偶数,且m为0时,答案的绝对值为1。
- 其余情况答案的绝对值均为【 n * (n-m+2) * (n-m+4) * ... * (n+m-4) * (n+m-2) 】/(m!)。(注意逆元的运用)
- 上面出现绝对值的情况,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;
}