模拟6-三角形详解
题目描述
自己思考:
当时自己做题目找规律的时候找错了推了一个(n+1)*(n-2)的公式结果就g了,10分。
解题思路:
首先第一步找出规律:
由此我们发现当在最底下添加一条边的时候,此时增加的三角形个数是:n+n-1+n-2+…+1 = (n+1)∗n2\frac{(n+1)*n}{2}2(n+1)∗n(其中n是线条的个数)。
推得公式an=an−1+((n+1)∗n2)a_n = a_{n-1} + (\frac{(n+1)*n}{2})an=an−1+(2(n+1)∗n),如果按照这个公式进行求解的话那么此时O(n)的时间复杂度能够解决70%的数据。
继续优化公式:
an=an−1+(n+1)∗n2a_n = a_{n-1} + \frac{(n+1)*n}{2}an=an−1+2(n+1)∗n
= an−2+(n−1)∗n2+n∗(n+1)2a_{n-2} + \frac {(n-1)*n}{2} +\frac{n*(n+1)}{2}an−2+2(n−1)∗n+2n∗(n+1)
=an−3+(n−2)∗(n−1)2+(n−1)∗n2+n∗(n+1)2a_{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+12+22+32+...+n22\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=1ni+∑i=1ni2)∗12(\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)∗n2+(n∗(n+1)∗(2∗n+1)6)∗12(\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;
}