题目描述
现有一个序列a1,a2,a3,···,an。
求
输入
输入包含多组样例。第一行一个整数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
样例输出
1 4 10 20
首先公式中的“∑”符号是累加的意思,第一个就好比i从1到n,可以用for循环表示,公式的大概表达
for(int sum=0,i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
sum+=a[j]-a[i];
}
但本题又时间限制,用暴力做法会时间超限,所以需要找出规律。
/// 对于n为奇数例如: a[1] a[2] a[3] a[4] a[5]
/// sum=a[5]-a[4]+a[5]-a[3]+a[5]-a[2]+a[5]-a[1]
/// +a[4]-a[3]+a[4]-a[2]+a[4]-a[1]
/// +a[3]-a[2]+a[3]-a[1]
/// +a[2]-a[1];
/// 对式子进行化简可以发现
/// a[5]的系数为4,a[4]的系数为2,a[3]的系数为0;
/// a[1]的系数为-4,a[2]的系数为-2;
/// 对于n为偶数道理一样,只是少了系数为0的项;
完整代码如下
#include <bits/stdc++.h>
using namespace std;
const int N=101000;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
long long int a[101000];
long long int sum=0;
for(int i=1;i<=n;i++) cin>>a[i];
int x=n/2;
int y=n-1;
int t=y;
for(int i=1;i<=x;i++)
{
sum-=y*a[i];
y-=2;
}
for(int i=0;i<x;i++)
{
sum+=t*a[n-i];
t-=2;
}
cout<<sum<<endl;
}
return 0;
}