题意:输入n,求解
∫01(x−x2)ndx的值,对998244353取模。
题解:多次运用分部积分能找到规律,猜出答案,答案正确性可通过数学分析法求证。
∫01(x−x2)ndx
⇒
∫01xn∗(1−x)ndx
=
n+1xn+1∗(1−x)n∣01−∫01(n+1xn+1∗[(1−x)n]′)dx
=
n+1n∗∫01[xn+1∗(1−x)n−1]dx
…
=
(n+1)∗(n+2)∗(n+3)∗...∗(2n)n∗(n−1)∗(n−2)∗....∗1∗∫01x2ndx
=
(n+1)∗(n+2)∗.....∗(2n+1)n!
=
(2n+1)!(n!)2
对(2n+10)阶乘进行预处理,O(1)的时间复杂度可得结果,取模时用逆元即可。
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int maxn=1e5+5;
const int mod=998244353;
const int N = 2e6+10;
ll qpow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans%mod;
}
ll inv(ll a)
{ return (qpow(a, mod-2)+mod)%mod; }
ll f[N+10];
void init()
{
f[0]=1;
for(int i=1;i<N;i++)
f[i]=i*f[i-1]%mod;
}
int main()
{
int n;
init();
while(scanf("%d",&n)!=EOF)
{
ll tmp=1;
ll ans=(f[n]*f[n]%mod*inv(f[2*n+1])+mod)%mod;
printf("%lld\n",ans);
}
}