原题题面
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Given n, find the value of
∫
0
1
(
x
−
x
2
)
n
d
x
\int_0^1 {(x-x^2)^n} \,{\rm d}x
∫01(x−x2)ndx.
It can be proved that the value is a rational number
p
q
\frac{p}{q}
qp.
Print the result as
p
⋅
q
−
1
m
o
d
998244353
p·q^{-1}\ mod\ 998244353
p⋅q−1 mod 998244353.
输入描述
he input consists of several test cases and is terminated by end-of-file.
Each test case contains an integer n.
- 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1≤n≤106
- The number of test cases does not exceed 1 0 5 10^5 105.
输入样例
1
2
3
输出样例
166374059
432572553
591816295
题面解析
比赛时使用了二项式定理拆分,果不其然算不出来了,于是看了题解用了Wallis积分
由于数据组数是
1
e
5
1e5
1e5,而
n
n
n有
1
e
6
1e6
1e6,因此考虑要去推结论。
由于积分形式是
(
X
X
X
X
X
)
n
(XXXXX)^n
(XXXXX)n的形式,且x的范围为
[
0
,
1
]
[0,1]
[0,1],故考虑Wallis积分/分部积分法。
简单来说就是如下结果:

(值得一提的是,Wallis积分其实本身就是多次分部积分法的结果,所以其实和分部积分法是同一个东西)
所以我们可以得到如下证明:

AC代码(183ms)
#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
long long quick_mul (long long a,long long b,long long c)//快速乘
{
return (a*b-(long long)((long double)a*b/c)*c+c)%c;
}
long long quick_pow (long long a,long long b,long long c)//快速幂
{
long long ans=1,base=a;
while (b!=0)
{
if (b&1)
ans=quick_mul (ans,base,c);
base=quick_mul (base,base,c);
b>>=1;
}
return ans%c;
}
long long factoral[2000050];
void init()
{
factoral[0]=1;
for(int i=1; i<=2000001; i++)
{
factoral[i]=i*factoral[i-1]%mod;
}
}
int main()
{
long long n;
init();
while(~scanf("%lld",&n))
{
long long sum=factoral[2*n+1];
long long sum1=quick_pow(factoral[n],mod-2,mod);
sum1=quick_pow(sum1,2,mod);
sum=sum*sum1%mod;
printf("%lld\n",quick_pow(sum,mod-2,mod));
}
}
后记
OEIS真好玩 A002457
博客介绍了在ACM竞赛中遇到的Wallis积分问题,探讨了如何利用Wallis积分解决给定的数值积分计算,并给出了针对大数n的高效算法实现,通过样例展示了计算过程。文章还提及Wallis积分与分部积分法的关系,并分享了在OEIS中的序列发现乐趣。
(2020牛客多校第一场J题)&spm=1001.2101.3001.5002&articleId=107303363&d=1&t=3&u=76fcc1132e1f45f5a2899c1d8a7e3091)
352

被折叠的 条评论
为什么被折叠?



