求答案3 相关代码和题解

现有一个序列a1,a2,a3,···,an。

 
由于答案可能较大,所以输出结果取模1e9+7 

输入

输入包含多组样例。第一行一个整数T(0<=T<=104)--代表测试样例的组数。
接下来T组数据
每组数据第一行包含一个整数n(1<=n<=105)--代表数组的长度。
接下来是一个实数序列a1,a2,a3,···,an(0<ai<=109)--数组元素。
保证n在所有用例中不超过105。

输出

每组样例输出一个整数代表答案

样例输入

4
2
1 2
3 
1 2 3
4 
1 2 3 4
5
1 2 3 4 5

样例输出

2
38
238
938

题目分析:

设共有4个数,设为a1,a2,a3,a4.

由题意可知题中让求得是

(a1^2  *  a2^2  -  a1*a2)  +  (a1^2 * a3^2 - a1*a3)  +  (a1^2 * a4^2 - a1*a4)

(a2^2  *  a3^2  -  a2*a3)  +  (a2^2 * a4^2 - a2*a4)

(a3^2  *  a4^2  -  a3*a4)

上面三个公式的和,但一时间看不出来规律,我整理了一下(将平方项和单项都单独写在一块):

a1^2  *  a4^2 +a2^2 * a4^2  +  a3^2 * a4^2     -     a1*a4+a2*a4+a3*a4

a1^2  *  a3^2 +a2^2 * a3^2     -     a1*a3+a2*a3

a1^2  *  a2^2     -     a1*a2

这次已经可以大致看出规律了,再进行一次整理可得:

(a1^2 + a2^2 + a3^2)*a4^2  -  (a1+a2+a3)*a4

(a1^2 + a2^2)*a3^2  -  (a1+a2)*a3

(a1^2)*a2^2  -  a1*a2

从这里我们就可以看出规律了,我们可以令 k为每项平方的和,令l为每项的和,令sum1为平方项的总和,sum2为单项的总和。最后让sum1-sum2就是最后的结果了。

注意:

由于数据最后结果过大,需要对每一次计算步骤和结果进行对1e9+7取余,还有就是因为每个步骤都会取余,所以取余后最终结果可能为负值,所以在输出结果时对最终结果加上1e9+7再取余1e9+7。

代码如下:

#include<bits/stdc++.h>
const int N = 100010, mod = 1e9 + 7;
long long a[N], sum1, sum2, sum, k, l;
using namespace std;
int main()
{
	int n, i;
	cin >> n;
	while (n--)
	{
		int m;
		cin >> m;
		for (i = 0; i < m; i++)
		{
			cin >> a[i];
		}
		sum1 = 0;
		k = 0;
		sum2 = 0;
		l = 0;
		for (i = 0; i < m; i++)
		{
			sum1 = (sum1 + k*a[i]) % mod;
			k = (k + a[i]) % mod;
			sum2 = (sum2 + l*a[i] * a[i]) % mod;
			l = (l + a[i] * a[i]) % mod;
		}
		sum = sum2 - sum1;
		cout << (sum + mod) % mod << endl;
	}
	return 0;
}

//若有疑问,欢迎留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值