首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/551/F
来源:牛客网
涉及:打表
题目如下:
对于这种题,一般都是在草稿纸上找规律,找到了规律,代码就OK了
首先说一说这么高大上的题目表达的什么意思:
∑
k
=
0
n
a
k
a
n
−
k
=
w
2
\sum_{k=0}^{n}a_{k}a_{n-k}=w^{2}
∑k=0nakan−k=w2
这个公式用中文理解起来就是,从k=0到k=n的所有ak与an-k乘积的和等于w2这个常数。
(比如当n=3时,
∑
k
=
0
n
a
k
a
n
−
k
(
n
=
3
)
=
a
0
a
3
+
a
1
a
2
+
a
2
a
1
+
a
3
a
0
=
w
2
\sum_{k=0}^{n}a_{k}a_{n-k}(n=3)=a_{0}a_{3}+a_{1}a_{2}+a_{2}a_{1}+a_{3}a_{0}=w^{2}
∑k=0nakan−k(n=3)=a0a3+a1a2+a2a1+a3a0=w2
,又如当n=2时,
∑
k
=
0
n
a
k
a
n
−
k
(
n
=
2
)
=
a
0
a
2
+
a
1
a
1
+
a
2
a
0
=
w
2
\sum_{k=0}^{n}a_{k}a_{n-k}(n=2)=a_{0}a_{2}+a_{1}a_{1}+a_{2}a_{0}=w^{2}
∑k=0nakan−k(n=2)=a0a2+a1a1+a2a0=w2)
懂了公式的意思,就可以开始找规律了,我们首先知道了a0=w,而且n只能为正整数,不仅如此,题目还有爱的告诉我们序列是唯一的。
所以
当n=1时,得到方程式
w
∗
a
1
+
a
1
∗
w
=
w
2
w*a_{1}+a_{1}*w=w^{2}
w∗a1+a1∗w=w2,解得
a
1
=
w
2
a_{1}=\frac{w}{2}
a1=2w
当n=2时,得到方程式
w
∗
a
2
+
w
2
∗
w
2
+
a
2
∗
w
=
w
2
w*a_{2}+\frac{w}{2}*\frac{w}{2}+a_{2}*w=w^{2}
w∗a2+2w∗2w+a2∗w=w2,解得
a
2
=
3
w
8
a_{2}=\frac{3w}{8}
a2=83w
当n=3时,得到方程式
w
∗
a
3
+
w
2
∗
3
w
8
+
3
w
8
∗
w
2
+
a
3
∗
w
=
w
2
w*a_{3}+\frac{w}{2}*\frac{3w}{8}+\frac{3w}{8}*\frac{w}{2}+a_{3}*w=w^{2}
w∗a3+2w∗83w+83w∗2w+a3∗w=w2,解得
a
3
=
5
w
16
a_{3}=\frac{5w}{16}
a3=165w
·
·
三个数据压根找不到规律,但是题目说为了让我们不难受,只让我们输出 2 n n ! 2^{n}n! 2nn!倍的an,那么可以找到 2 n n ! 2^{n}n! 2nn!倍an的规律
下面表格是部分数值
(其中
b
n
=
2
n
n
!
∗
a
n
b_{n}=2^{n}n! * a_{n}
bn=2nn!∗an):
n | a n a_{n} an | b n b_{n} bn | b n b_{n} bn与 b n − 1 b_{n-1} bn−1的关系 |
---|---|---|---|
1 | w 2 \frac{w}{2} 2w | w w w | ----- |
2 | 3 w 8 \frac{3w}{8} 83w | 3 w 3w 3w | b n = 3 b n − 1 b_{n}=3b_{n-1} bn=3bn−1 |
3 | 5 w 16 \frac{5w}{16} 165w | 15 w 15w 15w | b n = 5 b n − 1 b_{n}=5b_{n-1} bn=5bn−1 |
4 | 35 w 128 \frac{35w}{128} 12835w | 105 w 105w 105w | b n = 7 b n − 1 b_{n}=7b_{n-1} bn=7bn−1 |
5 | 63 w 256 \frac{63w}{256} 25663w | 945 w 945w 945w | b n = 9 b n − 1 b_{n}=9b_{n-1} bn=9bn−1 |
通过以上表格,可以通过不完全归纳法得到数列 b n b_{n} bn的递推式(这个也可以用数学归纳法求证):
b n + 1 = [ ( 2 n − 1 ) ( b n m o d 998244353 ) ] m o d 998244353 b_{n+1}=[(2n-1)(b_{n} mod 998244353)] mod 998244353 bn+1=[(2n−1)(bn mod 998244353)] mod 998244353 且 b 1 = w b_{1}=w b1=w
有了递推关系,可以把数据范围了所有的 b n b_{n} bn存到数组 b b b里面,然后直接拿出来用就可以了!
代码如下:
#include <iostream>
#define mod 998244353//取模值
#define size 1000005//数组b大小
using namespace std;
typedef long long ll;
ll b[size];
int w,q,t;//w,q均为题目中的变量,t是每次访问数组输入的值
void getb(ll b[]){//通过递推式得到数组b
for(int i=1;i<=1e6;i++)
b[i+1]=(b[i]%mod*(2*i+1))%mod;//递推式
}
int main(){
cin>>w>>q;
b[1]=w;//初始条件
getb(b);//得到数组b
while(q--){
scanf("%d",&t);
printf("%lld\n",b[t]);//访问数组b
}
return 0;
}