模拟6-三角形详解
题目描述
自己思考:
当时自己做题目找规律的时候找错了推了一个(n+1)*(n-2)的公式结果就g了,10分。
解题思路:
首先第一步找出规律:
由此我们发现当在最底下添加一条边的时候,此时增加的三角形个数是:n+n-1+n-2+…+1 =
(
n
+
1
)
∗
n
2
\frac{(n+1)*n}{2}
2(n+1)∗n(其中n是线条的个数)。
推得公式
a
n
=
a
n
−
1
+
(
(
n
+
1
)
∗
n
2
)
a_n = a_{n-1} + (\frac{(n+1)*n}{2})
an=an−1+(2(n+1)∗n),如果按照这个公式进行求解的话那么此时O(n)的时间复杂度能够解决70%的数据。
继续优化公式:
a
n
=
a
n
−
1
+
(
n
+
1
)
∗
n
2
a_n = a_{n-1} + \frac{(n+1)*n}{2}
an=an−1+2(n+1)∗n
=
a
n
−
2
+
(
n
−
1
)
∗
n
2
+
n
∗
(
n
+
1
)
2
a_{n-2} + \frac {(n-1)*n}{2} +\frac{n*(n+1)}{2}
an−2+2(n−1)∗n+2n∗(n+1)
=
a
n
−
3
+
(
n
−
2
)
∗
(
n
−
1
)
2
+
(
n
−
1
)
∗
n
2
+
n
∗
(
n
+
1
)
2
a_{n-3} + \frac {(n-2)*(n-1)}{2} + \frac {(n-1)*n}{2} +\frac{n*(n+1)}{2}
an−3+2(n−2)∗(n−1)+2(n−1)∗n+2n∗(n+1)
=
(
1
∗
2
+
2
∗
3
+
3
∗
4
+
4
∗
5
+
.
.
.
+
(
n
+
1
)
∗
n
)
2
\frac{(1 * 2 + 2 * 3 + 3 * 4 + 4 * 5 + ... + (n+1) * n)}{2}
2(1∗2+2∗3+3∗4+4∗5+...+(n+1)∗n)
=
1
+
2
+
3
+
4
+
.
.
.
+
n
+
1
2
+
2
2
+
3
2
+
.
.
.
+
n
2
2
\frac{1+2+3+4+...+n +1^{2} + 2^2+3^2+...+n^2}{2}
21+2+3+4+...+n+12+22+32+...+n2
=
(
∑
i
=
1
n
i
+
∑
i
=
1
n
i
2
)
∗
1
2
(\displaystyle \sum_{i=1}^{n} i + \displaystyle \sum_{i = 1}^{n}i^2) * \frac{1}{2}
(i=1∑ni+i=1∑ni2)∗21
=
(
(
n
+
1
)
∗
n
2
+
(
n
∗
(
n
+
1
)
∗
(
2
∗
n
+
1
)
6
)
∗
1
2
(\frac{(n+1)*n}{2} +\frac{(n*(n+1)*(2*n+1)}{6}) * \frac{1}{2}
(2(n+1)∗n+6(n∗(n+1)∗(2∗n+1))∗21
=
(
n
∗
(
n
+
1
)
∗
(
n
+
2
)
6
\frac{(n*(n+1)*(n+2)}{6}
6(n∗(n+1)∗(n+2)
观察这个公式其中n的取值范围1e9,如果直接相乘的话会造成数据溢出,所以此时可以利用边算边取余的方式,但是由于式子中带了一个除以6那么此时是没有办法直接边算边取余,可以发现n、n+1、n+2这三个数字连乘必然存在因子2和3可以先除掉。
AC代码
#include<iostream>
#define INF 0x3f3f3f3f
#define ll long long
#define N 1000005
#define M 100005
using namespace std;
int main(){
ll n;
cin>>n;
n--;
ll n1 = n+1,n2 = n+2;
if(n%2 == 0){
n /= 2;
}else if(n1%2 == 0){
n1 /=2;
}else if(n2%2 == 0){
n2 /= 2;
}
if(n%3 == 0){
n /= 3;
}else if(n1%3 == 0){
n1 /= 3;
}else if(n2%3 == 0){
n2 /= 3;
}
cout<<n*n1%998244353*n2%998244353;
return 0;
}