数学板块学习之差分应用及正整数的k次幂求和_4.计算题应用零的差分,求和k=1.-CSDN博客
找规律+打表+差分
题意:给定大三角形的层数n(1<=n<=1000000000),数大三角形中正三角形的个数
思路:
首先模拟一下可以初步找到一个规律:
那就是第n层的三角形一定有:
(1+2)个第(n-1)层的三角形
(1+2+3)个第(n-2)层的三角形
(1+2+3+4)个第(n-3)层的三角形
(1+2+3+4+...)个第1层的三角形
为了数三角形不重复,可以选择把每一层独有的正三角形计算出来,例如:
可以发现第三层独有的正三角形有3个,第四层有4个,以此类推
那么第n层所有的三角形就有
(1+2)*(n-1)+(1+2+3)(n-2)+(1+2+3+4)(n-3)+...+(1+2+3+4+...)*1个三角形
化简一下就是(n(n+1)+(n-1)*(n)+(n-2)(n-1)+...+1*2)/2
得到这个通项公式之后发现时间复杂度还是O(n),并且公式无法化简,也不能用矩阵快速幂
于是在前几项中打表找规律
有通项公式的很多题目最终的公式都是满足K次多项式的,于是尝试每两项相减,看一下是否满足这个K阶差分等于0
前置知识:
数学板块学习之差分应用及正整数的k次幂求和_4.计算题应用零的差分,求和k=1.-CSDN博客
发现确实满足K阶差分的性质,于是通过公式化简得到一个O(1)的公式:
代码实现:
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define pp pop_back()
#define int long long
#define lowbit(x) ((x)&(-x))
#define double long double
#define sf(x) scanf("%lld",&x)
#define sff(x,y) scanf("%lld %lld",&x,&y)
#define all(x) (x).begin(), (x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef unsigned long long ULL;
typedef pair<int,int>PII;
const int N=1e4+10,M=5e6+10,P=1e9+7;
int n,m,k;
int qmi(int a,int b)
{
int res=1;
while(b)
{
if(b&1)res=res*a%P;
a=a*a%P;
b>>=1;
}
return res;
}
void solve()
{
cin>>n;
int res=n*(n+1)%P*(n+2)%P*(n+3)%P*qmi(24,P-2)%P;
cout<<res<<"\n";
return ;
}
signed main()
{
IOS;
int T=1;
cin>>T;
while(T--)
solve();
return 0;
}