矩阵
题目描述
我们把1∼N2按下面矩阵的规律进行排列:
145161736⋯236151835987141934101112132033252423222132262728293031
请求第一列的累加和。
输入
每行一个整数N(1≤N≤109),如果N=0表示输入结束,这个样例不需要处理。
输出
每行输出一个样例的结果,因为这个值可能很大,请将其对1,000,000,007取模。
样例输入
1 2 3 1000000000 0
样例输出
1 5 10 499999881
思路
N范围:1≤N≤109,所以直接二维数组模拟或者遍历第1行到第N行累加答案肯定都是会超时的,所以直接推公式。
假设X为偶数,定义函数,那么
这里直接上结果了,反正主要就是找规律:
当N为偶数时:
当N为奇数时:
关键是取余问题。
取余
,对于这个公式,分子的三个部分相乘直接用乘法的取余规则求就可以了,问题主要在除法怎么取余除法取余解决方法_忆南妄北的博客-CSDN博客_除法取余,直接看这个链接,里面的结论记住就可以了没什么必要看证明。
上面链接的文章主要结论就是,在求时,可以求出b的逆元c,让,其中
所以在以上公式中,【除以6再对mod】取模就可以转化为【乘以6关于mod的逆元再对mod取模】
代码
#include<stdio.h>
#define MOD 1000000007
#define ie 166666668 // 6的逆元 ,为(6^(mod-2))%mod
typedef long long ll;
ll f(ll n) {
ll ans = (((n % MOD) * ((n + 1) % MOD) % MOD) * (n + 2) % MOD) % MOD;
ans = ans * ie % MOD;
return ans;
}
int main() {
ll n;
while (1) {
scanf("%I64d", &n);
if (n == 0) break;
if (n % 2 == 0) {
ll ans = (2 * f(n - 2) % MOD + n / 2 + n * n % MOD) % MOD; //找规律套公式
printf("%I64d\n", ans);
} else {
ll ans = (2 * f(n - 1) % MOD + (n + 1) / 2) % MOD; //找规律套公式
printf("%I64d\n", ans);
}
}
}