XTU OJ 1274 Matrix

文章讲述了如何对一个特定排列的矩阵第一列的累加和进行高效计算,避免了超时的二维数组模拟或遍历。通过推导公式,并利用除法的取模运算技巧,实现了大数情况下快速计算。当N为偶数或奇数时,有不同的计算公式,并给出了6的逆元在取模运算中的应用。
摘要由CSDN通过智能技术生成

矩阵

题目描述

我们把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为偶数,定义函数f(x)=0^2+2^2+4^2...+x^2,那么f(x)=\frac{x(x+1)(x+2)}{6}

这里直接上结果了,反正主要就是找规律:
当N为偶数时:ans=2*f(N-2)+\frac{N}{2}+N^2
当N为奇数时:ans=2*f(N-1)+\frac{(N+1)}{2}

关键是取余问题。

取余

f(x)=\frac{x(x+1)(x+2)}{6},对于这个公式,分子的三个部分相乘直接用乘法的取余规则求就可以了,问题主要在除法怎么取余除法取余解决方法_忆南妄北的博客-CSDN博客_除法取余,直接看这个链接,里面的结论记住就可以了没什么必要看证明。

上面链接的文章主要结论就是,在求(a/b)%mod时,可以求出b的逆元c,让(a/b)%mod = (a*c)%mod,其中c=b^{mod-2}

所以在以上公式中,【除以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);
		}
		
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值